iOS 11.0 中不推荐使用 touchIDLockout [英] touchIDLockout deprecated in iOS 11.0

查看:21
本文介绍了iOS 11.0 中不推荐使用 touchIDLockout的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Xcode 9 为 IOS11 编译我的应用程序时,我收到以下警告:

When compiling my Application with Xcode 9 for IOS11 I get the following warnings:

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 工作正常.

I'm using touchID but I'm not using touchIdLockout...cste and the touchID is working correctly.

如何删除这些警告?

我将此归结为一个原因.在我的代码中从 LocalAuthentication 框架中引用 LAError 就足以使这些警告出现.

I tracked this down to a single cause. It's enough to reference LAError from the LocalAuthentication framework in my code to make these warnings appear.

重现步骤(在 Xcode 9.2 中尝试过):

Steps to reproduce (tried in Xcode 9.2):

  1. 创建一个新的 iOS 应用(单一视图模板).请注意,iOS 部署目标设置为 iOS 11.2.
  2. 将这些行添加到 AppDelegate.swift:

import LocalAuthentication

appDidFinishLaunching 中的一行:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let _: LAError? = nil
    return true
}

  • 构建应用.

  • Build the app.

    let _: LAError?= nil 行足以使三个警告出现.但是,警告与任何特定的代码行无关.它们出现在构建日志中,没有任何文件/行引用:

    The let _: LAError? = nil line is enough to make the three warnings appear. The warnings are not associated with any particular line of code, though. They appear in the build log without any file/line reference:

    <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
    

    这是一个屏幕截图: 屏幕截图Xcode 中的警告

    以及示例项目: 示例项目下载 (Xcode 9.2)

    作为参考,我将此报告给了 Apple.雷达 #36028653.

    For reference, I reported this to Apple. Radar #36028653.

    推荐答案

    Short answer: 对我来说它看起来像一个编译器错误,导致通过导入定义多个常量的 C 枚举具有相同的值.

    Short answer: It looks like a compiler bug to me, caused by the import of a C enumeration which defines multiple constants with the same value.

    长答案:不幸的是,我没有如何避免弃用的解决方案警告,只是一个可能的解释是什么导致了它.

    Long answer: Unfortunately I do not have a solution how to avoid the deprecation warning, only a possible explanation what causes it.

    LAError 代码定义为 C 枚举 在 LocalAuthentication 框架中.这是一个该定义的摘录:

    The LAError codes are defined as a C enumeration in <LAError.h> in the LocalAuthentication framework. Here is an extract of that definition:

    // 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);
    

    可以看到旧"(已弃用)和新"错误代码使用相同的值.例如,LAErrorTouchIDNotAvailableLAErrorBiometryNotAvailable 都定义为 -6.

    One can see that "old" (deprecated) and the "new" error codes use the same values. For example, both LAErrorTouchIDNotAvailable and LAErrorBiometryNotAvailable are defined as -6.

    这在 C 中完全有效,但是 Swift enum 的原始值必须相互区分.显然 Swift 导入器解决了这个问题将新的/重复的案例映射到静态变量.

    That is perfectly valid in C, but the raw values of a Swift enum must be mutually distinct. Apparently the Swift importer solves that by mapping the new/duplicate cases to static variables.

    这里是 Swift 映射的摘录:

    Here is an extract of the Swift mapping:

    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 邮件列表中报告的问题

    And this seems to be the cause for the deprecation warnings, and also for the problem reported on the swift-users mailing list

    不可能写出详尽且无警告的LAError 的 switch 语句.

    that it is impossible to write an exhaustive and warning-free switch statement for LAError.

    为了证明我的猜想,我用一个自定义的方法复现了这个问题枚举:将以下定义添加到桥接头macOS 10.13 或 iOS 11 项目的文件:

    To prove my conjecture, I have reproduced the problem with a custom enumeration: Add the following definition to the bridging header file of an macOS 10.13 or iOS 11 project:

    #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 中

    This is imported to Swift as

     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 种情况,还有一个静态的重复值的属性.

    with 3 cases for the first (distinct) enum values, and a static property for the duplicate value.

    事实上,任何使用 MyEnum 都会触发弃用警告:

    And indeed, any use of MyEnum triggers a deprecation warning:

    // main.swift:
    print(MyEnum.A) // Or: let _: MyEnum? = nil
    
    // Build log:
    // <unknown>:0: warning: 'C' was deprecated in OS X 10.13: use MyEnumNewC
    

    另外,不能在一个新的枚举值中使用开关语句:

    In addition, it is not possible to use the new enum value in a switch statement:

    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
    

    即使编译器(显然)知道这些情况是详尽无遗的:

    even if the compiler (apparently) knows that these cases are exhaustive:

    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
    

    这在我看来像是一个编译器错误.

    This looks like a compiler bug to me.

    这篇关于iOS 11.0 中不推荐使用 touchIDLockout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆