- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
在为 IOS11 使用 Xcode 9 编译我的应用程序时,我收到以下警告:
warning: 'touchIDLockout' was deprecated in iOS 11.0: use LAErrorBiometryLockout
warning: 'touchIDNotEnrolled' was deprecated in iOS 11.0: use LAErrorBiometryNotEnrolled
warning: 'touchIDNotAvailable' was deprecated in iOS 11.0: use LAErrorBiometryNotAvailable
我正在使用 touchID 但我没有使用 touchIdLockout...cste 并且 touchID 工作正常。
如何删除这些警告?
我将此归结为一个原因。在我的代码中从 LocalAuthentication 框架引用 LAError
就足以使这些警告出现。
重现步骤(在 Xcode 9.2 中试过):
将这些行添加到 AppDelegate.swift
:
import LocalAuthentication
appDidFinishLaunching
中的一行:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let _: LAError? = nil
return true
}
构建应用。
let _: LAError? = nil
行足以使三个警告出现。不过,这些警告与任何特定代码行无关。它们出现在没有任何文件/行引用的构建日志中:
<unknown>:0: warning: 'touchIDLockout' was deprecated in iOS 11.0: use LAErrorBiometryLockout
<unknown>:0: warning: 'touchIDNotEnrolled' was deprecated in iOS 11.0: use LAErrorBiometryNotEnrolled
<unknown>:0: warning: 'touchIDNotAvailable' was deprecated in iOS 11.0: use LAErrorBiometryNotAvailable
这是一个截图: Screenshot of the warnings in Xcode
和示例项目: Sample project for download (Xcode 9.2)
作为引用,我已将此事报告给 Apple。雷达#36028653。
最佳答案
简短回答:对我来说这看起来像是一个编译器错误,导致通过导入定义多个常量的 C 枚举具有相同的值。
长答案:不幸的是,我没有如何避免弃用的解决方案警告,只是可能的解释是什么原因造成的。
LAError
代码被定义为 C 枚举 <LAError.h>
在 LocalAuthentication 框架中。这是一个该定义的摘录:
// Error codes
#define kLAErrorAuthenticationFailed -1
#define kLAErrorUserCancel -2
// ...
#define kLAErrorTouchIDNotAvailable -6
#define kLAErrorTouchIDNotEnrolled -7
#define kLAErrorTouchIDLockout -8
// ...
#define kLAErrorBiometryNotAvailable kLAErrorTouchIDNotAvailable
#define kLAErrorBiometryNotEnrolled kLAErrorTouchIDNotEnrolled
#define kLAErrorBiometryLockout kLAErrorTouchIDLockout
typedef NS_ENUM(NSInteger, LAError)
{
LAErrorAuthenticationFailed = kLAErrorAuthenticationFailed,
LAErrorUserCancel = kLAErrorUserCancel,
// ...
LAErrorTouchIDNotAvailable NS_ENUM_DEPRECATED(10_10, 10_13, 8_0, 11_0, "use LAErrorBiometryNotAvailable") = kLAErrorTouchIDNotAvailable,
LAErrorTouchIDNotEnrolled NS_ENUM_DEPRECATED(10_10, 10_13, 8_0, 11_0, "use LAErrorBiometryNotEnrolled") = kLAErrorTouchIDNotEnrolled,
LAErrorTouchIDLockout NS_ENUM_DEPRECATED(10_11, 10_13, 9_0, 11_0, "use LAErrorBiometryLockout")
__WATCHOS_DEPRECATED(3.0, 4.0, "use LAErrorBiometryLockout") __TVOS_DEPRECATED(10.0, 11.0, "use LAErrorBiometryLockout") = kLAErrorTouchIDLockout,
// ...
LAErrorBiometryNotAvailable NS_ENUM_AVAILABLE(10_13, 11_0) __WATCHOS_AVAILABLE(4.0) __TVOS_AVAILABLE(11.0) = kLAErrorBiometryNotAvailable,
LAErrorBiometryNotEnrolled NS_ENUM_AVAILABLE(10_13, 11_0) __WATCHOS_AVAILABLE(4.0) __TVOS_AVAILABLE(11.0) = kLAErrorBiometryNotEnrolled,
LAErrorBiometryLockout NS_ENUM_AVAILABLE(10_13, 11_0) __WATCHOS_AVAILABLE(4.0) __TVOS_AVAILABLE(11.0) = kLAErrorBiometryLockout,
// ...
} NS_ENUM_AVAILABLE(10_10, 8_0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0);
可以看到“旧”(已弃用)和"new"错误代码使用相同的值。例如,LAErrorTouchIDNotAvailable
和 LAErrorBiometryNotAvailable
定义为 -6
.
这在 C 中完全有效,但 Swift 的原始值 enum
必须互不相同。显然 Swift 进口商解决了这个问题将新的/重复的案例映射到静态变量。
这是 Swift 映射的摘录:
public struct LAError {
public init(_nsError: NSError)
public static var _nsErrorDomain: String { get }
public enum Code : Int {
case authenticationFailed
case userCancel
// ...
@available(iOS, introduced: 8.0, deprecated: 11.0, message: "use LAErrorBiometryNotAvailable")
case touchIDNotAvailable
@available(iOS, introduced: 8.0, deprecated: 11.0, message: "use LAErrorBiometryNotEnrolled")
case touchIDNotEnrolled
@available(iOS, introduced: 9.0, deprecated: 11.0, message: "use LAErrorBiometryLockout")
case touchIDLockout
// ...
@available(iOS 11.0, *)
public static var biometryNotAvailable: LAError.Code { get }
@available(iOS 11.0, *)
public static var biometryNotEnrolled: LAError.Code { get }
@available(iOS 11.0, *)
public static var biometryLockout: LAError.Code { get }
// ...
}
// ...
}
这似乎是弃用警告的原因,并且也针对 swift-users 邮件列表中报告的问题
不可能写出详尽无警告的LAError
的 switch 语句.
为了证明我的猜想,我用一个习惯重现了这个问题枚举:将以下定义添加到桥接 header macOS 10.13 或 iOS 11 项目的文件:
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, MyEnum)
{
MyEnumA = 1,
MyEnumB = 2,
MyEnumC NS_ENUM_DEPRECATED(10_10, 10_13, 8_0, 11_0, "use MyEnumNewC") = 3,
MyEnumNewC NS_ENUM_AVAILABLE(10_13, 11_0) = 3,
};
这是导入到 Swift 中的
public enum MyEnum : Int {
case A
case B
@available(OSX, introduced: 10_10, deprecated: 10_13, message: "use MyEnumNewC")
case C
@available(OSX 10_13, *)
public static var newC: MyEnum { get }
}
第一个(不同的)枚举值有 3 个案例,还有一个静态的重复值的属性。
事实上,任何对 MyEnum
的使用触发弃用警告:
// main.swift:
print(MyEnum.A) // Or: let _: MyEnum? = nil
// Build log:
// <unknown>:0: warning: 'C' was deprecated in OS X 10.13: use MyEnumNewC
此外,不可能在a中使用新的枚举值切换语句:
func foo(err: MyEnum) {
switch err {
case .A:
print("A")
case .B:
print("B")
case .newC:
print("C")
}
}
// Build log:
// main.swift:12:9: error: switch must be exhaustive
// <unknown>:0: warning: 'C' was deprecated in OS X 10.13: use MyEnumNewC
即使编译器(显然)知道这些情况是详尽无遗的:
func foo(err: MyEnum) {
switch err { // Switch must be exhaustive
case .A:
print("A")
case .B:
print("B")
case .newC:
print("C")
default:
print("default")
}
}
// Build log:
// <unknown>:0: warning: 'C' was deprecated in OS X 10.13: use MyEnumNewC
// main.swift:19:9: warning: default will never be executed
对我来说这看起来像是一个编译器错误。
关于ios - touchIDLockout 在 iOS 11.0 中被弃用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46455424/
我已经在 iOS 应用程序上成功实现了 Touch ID。但是,当用户尝试 Touch ID 失败次数过多时,我正在尝试处理错误情况。 我可以让用户关闭 Touch ID 对话框并通过用户名/密码文本
在为 IOS11 使用 Xcode 9 编译我的应用程序时,我收到以下警告: warning: 'touchIDLockout' was deprecated in iOS 11.0: use LAE
我是一名优秀的程序员,十分优秀!