AcuantTest 0.0.1-b

AcuantTest 0.0.1-b

Varun Garg 维护。



AcuantTest 0.0.1-b

  • Acuant Inc

Acuant iOS SDK v11.3.2

2020年3月

查看https://github.com/Acuant/iOSSDKV11/releases以获取发行说明。


简介

本文件提供了关于 Acuant iOS SDK 的详细信息。下面描述了 Acuant 推荐的工作流程。

注意可接受的图像应裁剪良好、清晰且无反光,分辨率至少为 300 dpi(用于数据采集)或 600 dpi(用于验证)。宽高比应合理并与身份证相匹配。


先决条件

  • iOS 版本 11.0 或更高

模块

SDK 包含以下模块

Acuant Face Capture Library (AcuantFaceCapture)

  • 使用原生 iOS 摄像头捕获人脸。

Acuant Passive Liveness Library (AcuantPassiveLiveness)

  • 使用专用算法检测真人

Acuant Common Library (AcuantCommon)

  • 包含所有共享内部模型和支持类

Acuant Camera Library (AcuantCamera)

  • 使用 iOS 原生摄像头库实现
  • 使用 AcuantImagePreparation 进行裁剪

Acuant Image Preparation Library (AcuantImagePreparation)

  • 包含所有图像处理,如裁剪、计算锐度和反光

Acuant Document Processing Library (AcuantDocumentProcessing)

  • 包含所有上传文档图像、处理和获取结果的方法

Acuant人脸匹配库(AcuantFaceMatch)

  • 包含一种用于匹配两张人脸图像的方法

Acuant HG 生存性库(AcuantHGLiveness)

  • 使用iOS本地摄像头库以专有算法捕获面部生存性

Acuant IP 生存性库(AcuantIPLiveness)

  • 使用专用算法检测真人

手动设置

  1. 添加以下依赖的嵌入框架
  • AcuantFaceCapture

  • AcuantPassiveLiveness

  • AcuantCommon

  • AcuantImagePreparation

  • AcuanCamera

  • AcuantDocumentProcessing

  • AcuantHGLiveness

  • AcuantFaceMatch

  • AcuantIPLiveness - iProov.framework - KeychainAccess.framework - SocketIO.framework - Starscream.framework - SwiftyJSON.framework

  1. 在Xcode中打开您的项目,导航到应用程序项目设置中的“构建阶段”标签。添加一个新的“运行脚本”。

  2. 将以下内容添加到脚本中。

    /usr/local/bin/carthage copy-frameworks
    
  3. 创建新的 inputFileList.xcfilelist 和 outputFileList.xcfilelist。将必要的框架添加到这两个文件中。请参阅存储库中的示例。

  4. 将.xcfilelist 添加到您的运行脚本中。获取更多信息,请访问 https://github.com/Carthage/Carthage


使用COCOAPODS

  1. 如果您正在使用COCOAPODS,则添加以下Podfile

     platform :ios, '11.0'
     pod 'AcuantiOSSDKV11', '~> 11.3.2'
    
  2. 在构建设置中为所有Acuant pod框架启用“BUILD_FOR_DISTRIBUTION”。

    • 使用Cocoapods。将其添加到Podfile中。

        post_install do |installer|
        	installer.pods_project.targets.each do |target|
        		if ['AcuantiOSSDKV11', 'KeychainAccess', 'Socket.IO-Client-Swift', 'Starscream' 'SwiftyJSON'].include? target.name
        			target.build_configurations.each do |config|
        				config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
        			end
        		end
        	end
        end
      
    • 手动


必需设置

  1. 创建一个名为 AcuantConfigplist 文件,其中包含以下详细信息

     <?xml version="1.0" encoding="UTF-8"?>
     <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
     <plist version="1.0">
     	<dict>
     		<key>acuant_username</key>
     		<string>[email protected]</string>
     		<key>acuant_password</key>
     		<string>xxxxxxxxxx</string>
     		<key>acuant_subscription</key>
     		<string>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</string>
     		<key>frm_endpoint</key>
     		<string>https://frm.acuant.net</string>
     		<key>passive_liveness_endpoint</key>
     		<string>https://passlive.acuant.net</string>
     		<key>med_endpoint</key>
     		<string>https://medicscan.acuant.net</string>
     		<key>assureid_endpoint</key>
     		<string>https://services.assureid.net</string>
     	</dict>
     </plist>
    

使用AcuantCamera捕获图像

  1. AcuantCamera最好在纵向模式下使用。在使用摄像头之前锁定应用的方向。

  2. 设置回调

     // Returns the image and barcodeString captured from device
     public protocol CameraCaptureDelegate {
     	func setCapturedImage(image:Image, barcodeString:String?)
     }
    
  3. 打开摄像头

    注意:现在选项通过一个选项对象定义。请参阅 AcuantCameraOptions 获取所有可配置的字段。

     let options = AcuantCameraOptions(autoCapture: true, hideNavigationBar: true)
     let documentCameraController = DocumentCameraController.getCameraController(delegate:self!, cameraOptions: options)
     
     navigationController.pushViewController(documentCameraController, animated: false)
    
  4. 获取捕获的图像

     public protocol CameraCaptureDelegate {
     	func setCapturedImage(image:Image, barcodeString:String?)
     }
    

使用DocumentCaptureSesssion(查看DocumentCameraController.swift以获取参考)进行自定义UI

  1. 获取DocumentCaptureSesssion。

     @objc public protocol DocumentCaptureDelegate {
         func readyToCapture() // gets called when triggering capture
         func documentCaptured(image:UIImage, barcodeString:String?) // gets called with captured result
     }
     
     let captureSession = DocumentCaptureSession.getDocumentCaptureSession(
     	delegate: DocumentCaptureDelegate, // session callback
     	frameDelegate: FrameAnalysisDelegate, // frame anaylsis callback
     	autoCapture:Bool, // enable frame analysis
     	captureDevice:AVCaptureDevice?) // AV Capture Device 
    
  2. 开始会话,然后将会话添加到AVCaptureVideoPreviewLayer。

     captureSession.start() // will start the capture session.
     let videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
     //add custom ui
    
  3. 接收帧结果。

     @objc public enum FrameResult : Int{
         case NO_DOCUMENT, // No document
         	SMALL_DOCUMENT, // Document is small
         	BAD_ASPECT_RATIO, // Document type does not match aspect ratio
         	GOOD_DOCUMENT, // Document is good to trigger capture
         	DOCUMENT_NOT_IN_FRAME // Document is not in frame
     }
     
     @objc public protocol FrameAnalysisDelegate{
         func onFrameAvailable(frameResult: FrameResult, points: Array<CGPoint>?)
     }
    
  4. 触发捕获。

     captureSession.enableCapture()
    
  5. DocumentCaptureDelegate将执行并带有结果

     func documentCaptured(image:UIImage, barcodeString:String?)
    

    注意: AcuantCamera依赖于<ссxsstrong>AcuantImagePreparation和< Получитеstrong>AcuantCommon。


AcuantImagePreparation

此模块包含所有图像准备功能。

  • 初始化

    AcuantImagePreparation.initialize(delegate: InitializationDelegate)
    
    public protocol InitializationDelegate {
    	func initializationFinished(error: AcuantError?);
    }
    

    注意:如果您在初始化时没有使用配置文件,那么请使用以下语句(提供适当的凭据以供用户名密码订阅ID使用)

    Credential.setUsername(username: "xxx")
    Credential.setPassword(password: "xxxx")
    Credential.setSubscription(subscription: "xxxxxx")
    
    let endpoints = Endpoints()
    endpoints.frmEndpoint = "https://frm.acuant.net"
    endpoints.healthInsuranceEndpoint = "https://medicscan.acuant.net"
    endpoints.idEndpoint = "https://services.assureid.net"
    
    Credential.setEndpoints(endpoints: endpoints)
    
    AcuantImagePreparation.initialize(delegate:self)
    

不带订阅ID的初始化

AcuantImagePreparation可以通过提供用户名和密码来初始化。但是,如果不提供订阅ID,则应用程序只能捕获图像并获取图像。没有订阅ID

  • 只能使用<олучитеstrong>AcuantCamera、AcuantImagePreparation和<учитеstrong>AcuantHGLiveness模块。

  • SDK可用于捕获身份证明文件。

  • 捕获的图像可以从SDK中导出。请参阅AcuantCamera项目中的DocumentCaptureDelegate协议。

    public protocol DocumentCaptureDelegate {
    	func readyToCapture()
    	func documentCaptured(image:UIImage, barcodeString:String?)
    }
    

裁剪

在捕获图像后,将其发送到裁剪库进行裁剪。

	public class func crop(data: CroppingData)->Image

	// CroppingData & Image are part of AcuantCommon
	// Sample

	let croppingData  = CroppingData()
    croppingData.image = image // UIImage

    let croppedImage = AcuantImagePreparation.crop(data: croppingData)

清晰度

sharpness方法返回 image 的清晰度值。如果清晰度值大于50,则认为图像是清晰的(不是模糊的)。

	public class func sharpness(image: UIImage)->Int

反射光

《glare` 方法返回图像的光线反射值。如果光线反射值为100,则图像不包含光线反射。如果光线反射值为0,则图像包含光线反射。

	public class func glare(image: UIImage)->Int

AcuantDocumentProcessing

在捕获文档图像后,可以使用以下步骤进行处理。

注意:如果上传失败并出现错误,请使用更好的图像重试图像上传。

  1. 创建实例

     public class func createInstance(options:IdOptions,delegate:CreateInstanceDelegate)
    
     public protocol CreateInstanceDelegate{
     	func instanceCreated(instanceId : String?,error:AcuantError?);
     }
    
  2. 上传图像

     public class func uploadImage(instancdId:String,data:IdData,options:IdOptions,delegate:UploadImageDelegate)
    
     public protocol UploadImageDelegate{
     	func imageUploaded(error: AcuantError?,classification:Classification?);
     }
    
  3. 获取数据

     public class func getData(instanceId:String,isHealthCard:Bool,delegate:GetDataDelegate?)
    
     public protocol UploadImageDelegate{
     	func imageUploaded(error: AcuantError?,classification:Classification?);
     }
    
  4. 删除实例

     public class func deleteInstance(instanceId : String,type:DeleteType, delegate:DeleteDelegate)
    
     public protocol DeleteDelegate {
     	func instanceDeleted(success : Bool)
     }
    


Acuant Face Capture

  1. (可选)设置默认图像。在示例应用程序项目的“Assets”目录中定位“acuant_default_face_image.png”。如果需要,将其添加到您的应用程序中。

  2. 在应用程序的可本地化字符串中设置本地化字符串

     "acuant_face_camera_initial" = "Align face to start capture";
     "acuant_face_camera_face_too_close" = "Too Close! Move Away";
     "acuant_face_camera_face_too_far" = "Move Closer";
     "acuant_face_camera_face_has_angle" =  "Face has Angle. Do not tilt";
     "acuant_face_camera_face_not_in_frame" =  "Move in Frame";
     "acuant_face_camera_face_moved" = "Hold Steady";
     "acuant_face_camera_capturing_2" = "Capturing\n2...";
     "acuant_face_camera_capturing_1" = "Capturing\n1...";	
    
  3. 设置任何必要的UI自定义

     class FaceAcuantCameraOptions{
     	public let totalCaptureTime: Int //totoal time to capture
     	public let bracketColorDefault: CGColor //bracket color default (no face)
     	public let bracketColorError: CGColor //bracket color error (error in face requirements)
     	public let bracketColorGood: CGColor //bracket color good (good face requirements)
     	public let fontColorDefault: CGColor //font color default
     	public let fontColorError: CGColor //font color error
     	public let fontColorGood: CGColor //font color good
     	public let defaultImageUrl: String //default image
     	public let showOval: Bool // show oval
     }
     
     //example
     let options = FaceAcuantCameraOptions()
    
  4. 获取控制器并将其推送到navigationController

     let controller = AcuantFaceCaptureController()
     	controller.options = options
     	controller.callback = { [weak self]
     		(image: UIImage?) in
     			
     			if(image == nil){
     				//user canceled
     			}
             
     	}
     		
     self.navigationController.pushViewController(controller, animated: true)
    
  5. 使用捕获结果使用回调。


Acuant Passive Liveness

Acuant建议使用`LiveAssessment`属性而不是分数来评估响应。《AcuantPassiveLiveness.startSelfieCapture`会返回一个重缩放的图像。

遵循以下建议,以有效地处理图像以实现被动活体识别。

图像要求

  • 高度:最小480像素,建议720或1080像素
  • 压缩:不建议对图像进行压缩(JPEG 70级别或以上是可以接受的)。为了获得最佳效果,请使用未压缩的图像。

人脸要求

  • 垂直旋转:面俯仰角和偏航角:从-20到20度,±3度
  • 平面旋转:面翻滚角:从-30到30度,±3度
  • 瞳距:眼睛之间的最小距离 90 ± 5像素
  • 面部大小:至少200像素的任何一个维度
  • 每张图像中的面部:1
  • 太阳镜:必须摘除

捕获要求

以下可能显着增加错误或错误结果

  • 使用运动模糊效果
  • 纹理过滤
  • 面部及其最近周围环境的聚光灯
  • 光线条件差或彩色光的环境

注意 此API不支持使用鱼眼镜头。

  1. 使用UIImage获取被动活度结果

     //liveness request
     class AcuantLivenessRequest{
         public let image: UIImage
         public init(image: UIImage)
     }
     
     //liveness response
     class AcuantLivenessResponse{
     	public let score: Int
     	public let result: AcuantLivenessAssessment
     	
     	public enum AcuantLivenessAssessment: String{
     		case Error
     		case PoorQuality
     		case Live
     		case NotLive
     	}
     }
     
     //liveness response
     class AcuantLivenessError{
     	public let errorCode: AcuantLivenessErrorCode?
     	public let description: String?
     	
     	
     	public enum AcuantLivenessErrorCode: String{
     	    case Unknown
     	    case FaceTooClose
     	    case FaceNotFound
     	    case FaceTooSmall
     	    case FaceAngleTooLarge
     	    case FailedToReadImage
     	    case InvalidRequest
     	    case InvalidRequestSettings
     	    case Unauthorized
     	    case NotFound
     	    case InternalError
     	    case InvalidJson
     	}
     }
     
     //example
     AcuantPassiveLiveness.postLiveness(request: AcuantLivenessRequest(image: image)){ [weak self]
     	(result: AcuantLivenessResponse?, error: AcuantLivenessError?) in
     		//response
     }
    

AcuantHGLiveness

该模块通过使用眨眼检测来检查是否存在活动(主题是否为活人)。该用户界面代码包含在示例应用(FaceLivenessCameraController.swift)中,客户可以根据具体需求对其进行修改。

Sample应用中的Acuant UI

// Code for HG Live controller
let liveFaceViewController = FaceLivenessCameraController()
liveFaceViewController.delegate : AcuantHGLiveFaceCaptureDelegate = self
self.navigationController.pushViewController(liveFaceViewController, animated: true)

自定义UI,创建面部活度捕捉会话

enum AcuantFaceType : Int {

    case NONE // No face
	
    case FACE_TOO_CLOSE // face is too close camera
	
    case FACE_MOVED // face moved from its original position
	
    case FACE_TOO_FAR // face is too far from camera
		
    case FACE_NOT_IN_FRAME // face is not in frame
    
    case FACE_GOOD_DISTANCE // face is good distance and in frame
}

public protocol AcuantHGLiveFaceCaptureDelegate {
		func liveFaceDetailsCaptured(liveFaceDetails: LiveFaceDetails?, faceType: AcuantHGLiveness.AcuantFaceType)
}

public class func getFaceCaptureSession(delegate:AcuantHGLiveFaceCaptureDelegate?, captureDevice: AVCaptureDevice?)-> FaceCaptureSession


let faceCaptureSession = AcuantHGLiveness.getFaceCaptureSession(delegate: self, captureDevice: captureDevice)

AcuantIPLiveness

AcuantIPLiveness模块用于检查主题是否为活人。

  1. 运行设置

     AcuantIPLiveness.performLivenessSetup(delegate:LivenessSetupDelegate)
    
     public protocol LivenessSetupDelegate{
     	func livenessSetupSucceeded(result:LivenessSetupResult) // Called when setup succeeds
     	func livenessSetupFailed(error:AcuantError) // Called when setup failed
     }
    
     public class LivenessSetupResult {
     	public var apiKey : String
     	public var token : String
     	public var userId : String
     	public var apiEndpoint : String
    
     }
    
  2. 进行活度测试

    注意 您可以使用 LivenessSetupResult 根据需要自定义界面。

     // Adjust various colors for the camera preview:
     setupResult.ui.lineColor = .white
     setupResult.ui.backgroundColor = .black
     setupResult.ui.loadingTintColor = .lightGray
     setupResult.ui.notReadyTintColor = .orange
     setupResult.ui.readyTintColor = .green
    
     setupResult.ui.title = "title" // Specify a custom title to be shown. Defaults to nil which will show an auto generated message. Set to empty string ("") to hide the message entirely.
     setupResult.ui.regularFont = "SomeFont"
     setupResult.ui.boldFont = "SomeFont-Bold"
     setupResult.ui.fonts = ["SomeFont", "SomeFont-Bold"] // If using custom fonts, specify them here (don't forget to add them to your Info.plist!)
     setupResult.ui.logoImage = UIImage(named: "foo")
     setupResult.ui.scanLineDisabled = false // Disables the vertical sweeping scanline while flashing
     setupResult.ui.autoStartDisabled = false // Disable the "auto start" countdown functionality. The user will have to tap the screen to start liveness test
    
     AcuantIPLiveness.performLivenessTest(setupResult:LivenessSetupResult, delegate:LivenessTestDelegate)
     
     public protocol LivenessTestDelegate{
     	func livenessTestCompleted() // This is for the test; called when Enroll is complete
     	func livenessTestCompletedWithError(error:AcuantError?) // This is for the test; called when Enroll is complete and error occured
     	func livenessTestProcessing(progress: Double, message: String) // This is for real-time notifications of progress of liveness test. It will be called after user captures live face. It is intended to be used for custom UI progress notification.
    
     }
    
  3. 获取活度测试结果

     AcuantIPLiveness.getLivenessTestResult(token:String,userId:String,delegate:LivenessTestResultDelegate)
     
     public protocol LivenessTestResultDelegate{
     	func livenessTestResultReceived(result:LivenessResult) // Called when test result was received successfully
     	func livenessTestResultReceiveFailed(error:AcuantError) // Called when test result was not received
     }
    
     public class LivenessTestResult {
     	public var passedLivenessTest : Bool = false
     	public var image : UIImage? = nil
     
     }
    

以下是依赖列表

  • iProov.framework
  • KeychainAccess.framework
  • SocketIO.framework
  • Startscream.framework
  • SwiftyJSON.framework

AcuantFaceMatch

此模块用于匹配两张面部图像

	public class func processFacialMatch(facialData : FacialMatchData, delegate : FacialMatchDelegate)

	public protocol FacialMatchDelegate {
		func facialMatchFinished(result:FacialMatchResult?)
	}

	public class FacialMatchData{
		public var faceImageOne : UIImage // Facial image from ID Card (image gets compressed by 80%)
		public var faceImageTwo : UIImage // Facial image from selfie capture during liveness check (image gets compressed by 80%)
	}

错误代码

public class AcuantErrorCodes{
	public static let ERROR_InvalidCredentials = -1
	public static let ERROR_InvalidLicenseKey = -2
	public static let ERROR_InvalidEndpoint = -3
	public static let ERROR_InitializationNotFinished = -4
	public static let ERROR_Network = -5
	public static let ERROR_InvalidJson = -6
	public static let ERROR_CouldNotCrop = -7
	public static let ERROR_NotEnoughMemory = -8
	public static let ERROR_BarcodeCaptureFailed = -9
	public static let ERROR_BarcodeCaptureTimedOut = -10
	public static let ERROR_BarcodeCaptureNotAuthorized = -11
	public static let ERROR_LiveFaceCaptureNotAuthorized = -12
	public static let ERROR_CouldNotCreateConnectInstance = -13
	public static let ERROR_CouldNotUploadConnectImage = -14
	public static let ERROR_CouldNotUploadConnectBarcode = -15
	public static let ERROR_CouldNotGetConnectData = -16
	public static let ERROR_CouldNotProcessFacialMatch = -17
	public static let ERROR_CardWidthNotSet = -18
	public static let ERROR_CouldNotGetHealthCardData = -19
	public static let ERROR_CouldNotClassifyDocument = -20
	public static let ERROR_LowResolutionImage = -21
	public static let ERROR_BlurryImage = -22
	public static let ERROR_ImageWithGlare = -23
	public static let ERROR_CouldNotGetIPLivenessToken = -24
	public static let ERROR_NotALiveFace = -25
	public static let ERROR_CouldNotAccessLivenessData = -26
}

错误描述

public class AcuantErrorDescriptions {
	public static let ERROR_DESC_InvalidCredentials = "Invalid credentials"
	public static let ERROR_DESC_InvalidLicenseKey = "Invalid License Key"
	public static let ERROR_DESC_InvalidEndpoint = "Invalid endpoint"
	public static let ERROR_DESC_Network = "Network problem"
	public static let ERROR_DESC_InitializationNotFinished = "Initialization not finished"
	public static let ERROR_DESC_InvalidJson = "Invalid Json response"
	public static let ERROR_DESC_CouldNotCrop = "Could not crop image"
	public static let ERROR_DESC_BarcodeCaptureFailed = "Barcode capture failed"
	public static let ERROR_DESC_BarcodeCaptureTimedOut = "Barcode capture timed out"
	public static let ERROR_DESC_BarcodeCaptureNotAuthorized = "Barcode capture is not authorized"
	public static let ERROR_DESC_LiveFaceCaptureNotAuthorized = "Live face capture is not authorized"
	public static let ERROR_DESC_CouldNotCreateConnectInstance = "Could not create connect Instance"
	public static let ERROR_DESC_CouldNotUploadConnectImage = "Could not upload image to connect instance"
	public static let ERROR_DESC_CouldNotUploadConnectBarcode = "Could not upload barcode to connect instance"
	public static let ERROR_DESC_CouldNotGetConnectData = "Could not get connect image data"
	public static let ERROR_DESC_CardWidthNotSet = "Card width not set"
	public static let ERROR_DESC_CouldNotGetHealthCardData = "Could not get health card data"
	public static let ERROR_DESC_CouldNotClassifyDocument = "Could not classify document"
	public static let ERROR_DESC_LowResolutionImage = "Low resolution image"
	public static let ERROR_DESC_BlurryImage = "Blurry image"
	public static let ERROR_DESC_ImageWithGlare = "Image has glare"
	public static let ERROR_DESC_CouldNotGetIPLivenessToken = "Could not get face liveness token"
	public static let ERROR_DESC_NotALiveFace = "Not a live face"
	public static let ERROR_DESC_CouldNotAccessLivenessData = "Could not access liveness data"
}

图片

public class Image {
	public var image: UIImage? = nil
	public var dpi: Int = 0 // dpi value of the captured image
	public var error: AcuantError? = nil
	public var isCorrectAspectRatio = false // If the captured image has the correct aspect ratio
	public var aspectRatio: Float = 0.0 // Aspect ratio of the captured image
	public var points: Array<CGPoint> = []
	public var isPassport = false
	public init(){}
}

AcuantCameraOptions

public class AcuantCameraOptions {
    timeInMsPerDigit: Int = 900,
    digitsToShow: Int = 2,
    allowBox: Bool = true,
    autoCapture: Bool = true,
    hideNavigationBar: Bool = true,
    bracketLengthInHorizontal: Int = 80,
    bracketLengthInVertical: Int = 50,
    defaultBracketMarginWidth: CGFloat = 0.5,
    defaultBracketMarginHeight: CGFloat = 0.6,
    colorHold: CGColor = UIColor.yellow.cgColor,
    colorCapturing: CGColor = UIColor.green.cgColor,
    colorBracketAlign: CGColor = UIColor.black.cgColor,
    colorBracketCloser: CGColor = UIColor.red.cgColor,
    colorBracketHold: CGColor = UIColor.yellow.cgColor,
    colorBracketCapture: CGColor = UIColor.green.cgColor
}

IdOptions

public class IdOptions {
    public var cardSide: CardSide = CardSide.Front
    public var isHealthCard: Bool = false
    public var isRetrying: Bool = false
    public var authenticationSensitivity: AuthenticationSensitivity = AuthenticationSensitivity.Normal
}

常见问题

为什么在Apple App Store发布应用时会出现“不支持架构”错误?

所有框架都是 fat(多架构)二进制文件,包含 切片,用于 armv7arm64 i386x86(64) CPU 架构。ARM 切片由物理 iOS 设备使用,而 i386 和 x86(64) 用于模拟器。

使用 lipo 命令来检查二进制中包含哪些切片

	lipo -info <path to the file>

您也可以使用 lipo 命令来删除不需要的切片

	lipo -remove i386 <Path to the file> -o <Output file path>

	lipo -remove x86_64 <Path to the file> -o <Output file path>

为什么在存档样本应用程序时出现代码签名“AcuantCommon.framework”错误?

Acuant 为所有模拟器和设备所需的 CPU 架构提供支持。然而,在导出或发布到 Test Flight/App Store 时,应从框架二进制文件中删除模拟器架构(i386 和 x86(64))。

  1. 存档应用程序。
  2. 选择存档,然后点击 分发应用> App Store> 导出

我该如何混淆我的 iOS 应用程序?

Acuant 不提供混淆工具,但是有一些第三方工具可供选择,包括 iXGuardArxan


版权所有 2020 Acuant Inc. 保留所有权利。

本文档包含由 Acuant 和其各自许可方拥有的专有和保密信息及创意作品。未经 Acuant 事先书面明确许可,禁止以任何形式或任何手段全部或部分使用、复制、发布、分发、展示、修改或传输此类技术。除非 Acuant 以书面形式明确提供,否则拥有此信息不视为授予任何 Acuant 知识产权的许可或权利,无论是由于先占、暗示还是其他方式。

AssureID 和 i-Dentify 是 Acuant Inc. 的商标。本文档中提到的其他 Acuant 产品或服务名称或标志是 Acuant 的商标或注册商标。

所有 3M 商标是 Gemalto Inc. 的商标。

Windows 是微软公司的注册商标。

本文档可能提及 Acuant 之外的公司的一些产品、服务或公司名称,仅用于识别目的。此类名称通常被视为商标或服务标志。在实际中,如果 Acuant 明知有此类主张,该名称将首字母大写或全部大写。但是,您应联系有关公司以获取有关此类名称及其注册状态的更完整信息。

有关技术支持,请访问:https://support.acuant.com

Acuant Inc. 6080 Center Drive, Suite 850, Los Angeles, CA 90045