Post

接入亚马逊人脸识别解决编译支持iOS12、canImport、@available、#available

1、由于https://github.com/aws-amplify/amplify-ui-swift-liveness使用SwiftUIhttps://github.com/aws-amplify/amplify-swift库,这这两个库必须要iOS13以上
2、再加上使用了iOS14以上的一些特殊API,导致引入了AmplifyUILiveness后,整个项目最少也要支持iOS14,与我们维护的App需要支持到iOS12不一致,为了最大限度使用App,可以让App可以编译支持iOS12的系统,但是亚马逊人脸识别在iOS14才使用

github地址:https://github.com/h42330789/amplify-ui-swift-liveness/tree/compile_ios13_support_ios14

解决方案一: 对引入的库进行修改源码,增加在引入库的地方增加配置 1、对所有直接引入SwiftUI的地方,使用#if canImport(XXX) import xxx #endif
2、对所有使用iOS14的struct、class、extension等开始出增加@available(iOS 14.0, *)
3、在使用时业务代码调用的地方使用条件判断引入if #available(iOS 14.0, *) { ... }
Demo:FaceLivenessDetectionView.swift如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 通过条件引入SwiftUI
#if canImport(SwiftUI)
import SwiftUI
#endif

import AWSClientRuntime
import protocol AWSPluginsCore.AWSCredentialsProvider
import AWSPredictionsPlugin
import AVFoundation
import Amplify
@_spi(PredictionsFaceLiveness) import AWSPredictionsPlugin

// 增加iOS版本号编译
@available(iOS 14.0, *)
public struct FaceLivenessDetectorView: View {
    // ....
}

调用Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 业务代码调用地方
class ViewController: UIViewController {
   func showMyTestSwiftUI() {
        if #available(iOS 14, *) {
            let vc = UIHostingController(rootView: MyFaceView())
            self.navigationController?.pushViewController(vc, animated: true)
        }  
    }
}
@available(iOS 14.0, *)
struct MyFaceView: View {
  @State private var isPresentingLiveness = true
  @State var sessionID = xxxxx"
  @State var region = "xxxx"
    
  var body: some View {
    FaceLivenessDetectorView(
      sessionID: sessionID,
      credentialsProvider: MyCredentialsProvider(),
      region: region,
      isPresented: $isPresentingLiveness,
      onCompletion: { result in
        switch result {
        case .success:
            print("success")
            break
          // ...
        case .failure(let error):
            print(error)
            break
          // ...
        }
      }
    )
  }
}
@available(iOS 14.0, *)
struct MyCredentialsProvider: AWSCredentialsProvider {
    func fetchAWSCredentials() async throws -> AWSCredentials {
        return MyAWSCredentials()
    }
    
    struct MyAWSCredentials: AWSCredentials {
        var accessKeyId: String = "xxxxx"

        var secretAccessKey: String = "xxxxx"
    }
}

This post is licensed under CC BY 4.0 by the author.