Repository: micyo202/YZAuthID Branch: master Commit: 417c18531fe3 Files: 24 Total size: 48.9 KB Directory structure: gitextract_tlh1k132/ ├── .gitignore ├── .travis.yml ├── ExportOptions.plist ├── LICENSE ├── README.md ├── Supporting Files/ │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets/ │ │ └── AppIcon.appiconset/ │ │ └── Contents.json │ ├── Base.lproj/ │ │ └── LaunchScreen.storyboard │ ├── Images.xcassets/ │ │ ├── Contents.json │ │ ├── auth_face.imageset/ │ │ │ └── Contents.json │ │ └── auth_finger.imageset/ │ │ └── Contents.json │ ├── Info.plist │ └── main.m ├── YZAuthID/ │ ├── YZAuthID.h │ └── YZAuthID.m ├── YZAuthID.podspec ├── YZAuthID.xcodeproj/ │ ├── project.pbxproj │ └── project.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── YZAuthIDDemo/ │ ├── Base.lproj/ │ │ └── Main.storyboard │ ├── ViewController.h │ └── ViewController.m └── archive.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore ## Build generated build/ DerivedData/ ## Various settings *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata/ ## Other *.moved-aside *.xccheckout *.xcscmblueprint ## Obj-C/Swift specific *.hmap *.ipa *.dSYM.zip *.dSYM # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control # # Pods/ # Carthage # # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts Carthage/Build # fastlane # # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the # screenshots whenever they are needed. # For more information about the recommended setup visit: # https://docs.fastlane.tools/best-practices/source-control/#source-control fastlane/report.xml fastlane/Preview.html fastlane/screenshots fastlane/test_output # Code Injection # # After new code Injection tools there's a generated folder /iOSInjectionProject # https://github.com/johnno1962/injectionforxcode iOSInjectionProject/ ================================================ FILE: .travis.yml ================================================ language: objective-c osx_image: xcode10 xcode_project: YZAuthID.xcodeproj xcode_scheme: YZAuthID before_install: - env - xcodebuild -version - xcodebuild -showsdks - xcpretty --version script: - set -o pipefail - xcodebuild clean build -project "$TRAVIS_XCODE_PROJECT" -scheme "$TRAVIS_XCODE_SCHEME" -sdk iphonesimulator PLATFORM_NAME=iphonesimulator -configuration Debug | xcpretty -c ================================================ FILE: ExportOptions.plist ================================================ compileBitcode method development ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 Yanzheng Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # YZAuthID [![Build Status](https://travis-ci.org/micyo202/YZAuthID.svg)](https://travis-ci.org/micyo202/YZAuthID) [![Version](https://img.shields.io/badge/version-2.1.0-yellow.svg)](https://github.com/micyo202/YZAuthID) [![Cocoapods](https://img.shields.io/badge/pod-1.10.0-green.svg)](https://cocoapods.org/?q=YZAuthID) [![Platform](https://img.shields.io/badge/platform-ios-red.svg)](https://github.com/micyo202/YZAuthID) [![License MIT](https://img.shields.io/badge/license-MIT-lightgrey.svg)](https://github.com/micyo202/YZAuthID/blob/master/LICENSE) [![GitHub stars](https://img.shields.io/github/stars/micyo202/YZAuthID.svg?style=social&label=Stars)](https://github.com/micyo202/YZAuthID) [![GitHub forks](https://img.shields.io/github/forks/micyo202/YZAuthID.svg?style=social&label=Fork)](https://github.com/micyo202/YZAuthID) 仅需一个回调方法即可轻松实现iOS TouchID(指纹)/ FaceID(面容)验证功能,代码简洁易懂。 #### 详细使用方法及介绍请参考[简书](https://www.jianshu.com/p/da752036b2f4) #### 实例效果图: 指纹1 指纹2 指纹3 面容1 面容2 面容3 ================================================ FILE: Supporting Files/AppDelegate.h ================================================ // // AppDelegate.h // YZAuthID // // Created by Apple on 2018/07/26. // Copyright © 2018年 Yanzheng. All rights reserved. // #import @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @end ================================================ FILE: Supporting Files/AppDelegate.m ================================================ // // AppDelegate.m // YZAuthID // // Created by Apple on 2018/07/26. // Copyright © 2018年 Yanzheng. All rights reserved. // #import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. // 设置顶部状态栏字体为白色 [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } @end ================================================ FILE: Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "20x20", "scale" : "2x" }, { "idiom" : "iphone", "size" : "20x20", "scale" : "3x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "1x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "2x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "1x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x" }, { "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" }, { "idiom" : "ios-marketing", "size" : "1024x1024", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Supporting Files/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: Supporting Files/Images.xcassets/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Supporting Files/Images.xcassets/auth_face.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "auth_face@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Supporting Files/Images.xcassets/auth_finger.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "auth_finger@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Supporting Files/Info.plist ================================================ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion 1 LSRequiresIPhoneOS NSFaceIDUsageDescription 允许设备访问Face ID UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIViewControllerBasedStatusBarAppearance ================================================ FILE: Supporting Files/main.m ================================================ // // main.m // YZAuthID // // Created by Apple on 2018/07/26. // Copyright © 2018年 Yanzheng. All rights reserved. // #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: YZAuthID/YZAuthID.h ================================================ /************************************************************ Class : YZAuthID.h Describe : TouchID/FaceID 认证方法 Company : Micyo Author : Yanzheng Date : 2018-07-26 Version : 2.0 Declare : Copyright © 2018 Yanzheng. All rights reserved. ************************************************************/ #import /** * TouchID/FaceID 状态 */ typedef NS_ENUM(NSUInteger, YZAuthIDState){ /** * 当前设备不支持TouchID/FaceID */ YZAuthIDStateNotSupport = 0, /** * TouchID/FaceID 验证成功 */ YZAuthIDStateSuccess = 1, /** * TouchID/FaceID 验证失败 */ YZAuthIDStateFail = 2, /** * TouchID/FaceID 被用户手动取消 */ YZAuthIDStateUserCancel = 3, /** * 用户不使用TouchID/FaceID,选择手动输入密码 */ YZAuthIDStateInputPassword = 4, /** * TouchID/FaceID 被系统取消 (如遇到来电,锁屏,按了Home键等) */ YZAuthIDStateSystemCancel = 5, /** * TouchID/FaceID 无法启动,因为用户没有设置密码 */ YZAuthIDStatePasswordNotSet = 6, /** * TouchID/FaceID 无法启动,因为用户没有设置TouchID/FaceID */ YZAuthIDStateTouchIDNotSet = 7, /** * TouchID/FaceID 无效 */ YZAuthIDStateTouchIDNotAvailable = 8, /** * TouchID/FaceID 被锁定(连续多次验证TouchID/FaceID失败,系统需要用户手动输入密码) */ YZAuthIDStateTouchIDLockout = 9, /** * 当前软件被挂起并取消了授权 (如App进入了后台等) */ YZAuthIDStateAppCancel = 10, /** * 当前软件被挂起并取消了授权 (LAContext对象无效) */ YZAuthIDStateInvalidContext = 11, /** * 系统版本不支持TouchID/FaceID (必须高于iOS 8.0才能使用) */ YZAuthIDStateVersionNotSupport = 12 }; @interface YZAuthID : LAContext typedef void (^YZAuthIDStateBlock)(YZAuthIDState state, NSError *error); /** * 启动TouchID/FaceID进行验证 * @param describe TouchID/FaceID显示的描述 * @param block 回调状态的block */ - (void)yz_showAuthIDWithDescribe:(NSString *)describe block:(YZAuthIDStateBlock)block; @end ================================================ FILE: YZAuthID/YZAuthID.m ================================================ /************************************************************ Class : YZAuthID.m Describe : TouchID/FaceID 认证方法 Company : Micyo Author : Yanzheng Date : 2018-07-26 Version : 2.0 Declare : Copyright © 2018 Yanzheng. All rights reserved. ************************************************************/ #import "YZAuthID.h" #import #define iPhoneX (UIScreen.mainScreen.bounds.size.width >= 375.f && UIScreen.mainScreen.bounds.size.height >= 812.f) @implementation YZAuthID + (instancetype)sharedInstance { static YZAuthID *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[YZAuthID alloc] init]; }); return instance; } - (void)yz_showAuthIDWithDescribe:(NSString *)describe block:(YZAuthIDStateBlock)block { if(!describe) { if(iPhoneX){ describe = @"验证已有面容"; }else{ describe = @"通过Home键验证已有指纹"; } } if (NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"系统版本不支持TouchID/FaceID (必须高于iOS 8.0才能使用)"); block(YZAuthIDStateVersionNotSupport, nil); }); return; } LAContext *context = [[LAContext alloc] init]; // 认证失败提示信息,为 @"" 则不提示 context.localizedFallbackTitle = @"输入密码"; NSError *error = nil; // LAPolicyDeviceOwnerAuthenticationWithBiometrics: 用TouchID/FaceID验证 // LAPolicyDeviceOwnerAuthentication: 用TouchID/FaceID或密码验证, 默认是错误两次或锁定后, 弹出输入密码界面(本案例使用) if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error]) { [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:describe reply:^(BOOL success, NSError * _Nullable error) { if (success) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 验证成功"); block(YZAuthIDStateSuccess, error); }); }else if(error){ if (@available(iOS 11.0, *)) { switch (error.code) { case LAErrorAuthenticationFailed:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 验证失败"); block(YZAuthIDStateFail, error); }); break; } case LAErrorUserCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 被用户手动取消"); block(YZAuthIDStateUserCancel, error); }); } break; case LAErrorUserFallback:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"用户不使用TouchID/FaceID,选择手动输入密码"); block(YZAuthIDStateInputPassword, error); }); } break; case LAErrorSystemCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 被系统取消 (如遇到来电,锁屏,按了Home键等)"); block(YZAuthIDStateSystemCancel, error); }); } break; case LAErrorPasscodeNotSet:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 无法启动,因为用户没有设置密码"); block(YZAuthIDStatePasswordNotSet, error); }); } break; //case LAErrorTouchIDNotEnrolled:{ case LAErrorBiometryNotEnrolled:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 无法启动,因为用户没有设置TouchID/FaceID"); block(YZAuthIDStateTouchIDNotSet, error); }); } break; //case LAErrorTouchIDNotAvailable:{ case LAErrorBiometryNotAvailable:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 无效"); block(YZAuthIDStateTouchIDNotAvailable, error); }); } break; //case LAErrorTouchIDLockout:{ case LAErrorBiometryLockout:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 被锁定(连续多次验证TouchID/FaceID失败,系统需要用户手动输入密码)"); block(YZAuthIDStateTouchIDLockout, error); }); } break; case LAErrorAppCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前软件被挂起并取消了授权 (如App进入了后台等)"); block(YZAuthIDStateAppCancel, error); }); } break; case LAErrorInvalidContext:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前软件被挂起并取消了授权 (LAContext对象无效)"); block(YZAuthIDStateInvalidContext, error); }); } break; default: break; } } else { // iOS 11.0以下的版本只有 TouchID 认证 switch (error.code) { case LAErrorAuthenticationFailed:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 验证失败"); block(YZAuthIDStateFail, error); }); break; } case LAErrorUserCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 被用户手动取消"); block(YZAuthIDStateUserCancel, error); }); } break; case LAErrorUserFallback:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"用户不使用TouchID,选择手动输入密码"); block(YZAuthIDStateInputPassword, error); }); } break; case LAErrorSystemCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 被系统取消 (如遇到来电,锁屏,按了Home键等)"); block(YZAuthIDStateSystemCancel, error); }); } break; case LAErrorPasscodeNotSet:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 无法启动,因为用户没有设置密码"); block(YZAuthIDStatePasswordNotSet, error); }); } break; case LAErrorBiometryNotEnrolled:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 无法启动,因为用户没有设置TouchID"); block(YZAuthIDStateTouchIDNotSet, error); }); } break; //case :{ case LAErrorBiometryNotAvailable:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 无效"); block(YZAuthIDStateTouchIDNotAvailable, error); }); } break; case LAErrorBiometryLockout:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 被锁定(连续多次验证TouchID失败,系统需要用户手动输入密码)"); block(YZAuthIDStateTouchIDLockout, error); }); } break; case LAErrorAppCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前软件被挂起并取消了授权 (如App进入了后台等)"); block(YZAuthIDStateAppCancel, error); }); } break; case LAErrorInvalidContext:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前软件被挂起并取消了授权 (LAContext对象无效)"); block(YZAuthIDStateInvalidContext, error); }); } break; default: break; } } } }]; }else{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前设备不支持TouchID/FaceID"); block(YZAuthIDStateNotSupport, error); }); } } @end ================================================ FILE: YZAuthID.podspec ================================================ Pod::Spec.new do |s| s.name = 'YZAuthID' s.version = '2.1.0' s.summary = 'TouchID/FaceID auth.' s.homepage = 'https://github.com/micyo202/YZAuthID' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = {'Yanzheng' => 'micyo202@163.com'} s.platform = :ios, '12.0' s.ios.deployment_target = '12.0' s.source = {:git => 'https://github.com/micyo202/YZAuthID.git', :tag => s.version} s.source_files = 'YZAuthID/**/*.{h,m}' s.requires_arc = true end ================================================ FILE: YZAuthID.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 48; objects = { /* Begin PBXBuildFile section */ 182B79E31FECDBAF005E0E81 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 182B79E21FECDBAF005E0E81 /* AppDelegate.m */; }; 182B79E61FECDBAF005E0E81 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 182B79E51FECDBAF005E0E81 /* ViewController.m */; }; 182B79E91FECDBAF005E0E81 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 182B79E71FECDBAF005E0E81 /* Main.storyboard */; }; 182B79EB1FECDBAF005E0E81 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 182B79EA1FECDBAF005E0E81 /* Assets.xcassets */; }; 182B79EE1FECDBAF005E0E81 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 182B79EC1FECDBAF005E0E81 /* LaunchScreen.storyboard */; }; 182B79F11FECDBAF005E0E81 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 182B79F01FECDBAF005E0E81 /* main.m */; }; 182B79FC1FECDCDB005E0E81 /* YZAuthID.m in Sources */ = {isa = PBXBuildFile; fileRef = 182B79FB1FECDCDB005E0E81 /* YZAuthID.m */; }; 182B79FE1FECEE5A005E0E81 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 182B79FD1FECEE5A005E0E81 /* Images.xcassets */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 182B79DE1FECDBAF005E0E81 /* YZAuthID.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YZAuthID.app; sourceTree = BUILT_PRODUCTS_DIR; }; 182B79E11FECDBAF005E0E81 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 182B79E21FECDBAF005E0E81 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 182B79E41FECDBAF005E0E81 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 182B79E51FECDBAF005E0E81 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 182B79E81FECDBAF005E0E81 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 182B79EA1FECDBAF005E0E81 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 182B79ED1FECDBAF005E0E81 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 182B79EF1FECDBAF005E0E81 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 182B79F01FECDBAF005E0E81 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 182B79FA1FECDCDB005E0E81 /* YZAuthID.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YZAuthID.h; sourceTree = ""; }; 182B79FB1FECDCDB005E0E81 /* YZAuthID.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = YZAuthID.m; sourceTree = ""; }; 182B79FD1FECEE5A005E0E81 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 182B79DB1FECDBAF005E0E81 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 182B79D51FECDBAF005E0E81 = { isa = PBXGroup; children = ( 182B79F91FECDBF6005E0E81 /* Supporting Files */, 182B79F71FECDBD6005E0E81 /* YZAuthIDDemo */, 182B79E01FECDBAF005E0E81 /* YZAuthID */, 182B79DF1FECDBAF005E0E81 /* Products */, ); sourceTree = ""; }; 182B79DF1FECDBAF005E0E81 /* Products */ = { isa = PBXGroup; children = ( 182B79DE1FECDBAF005E0E81 /* YZAuthID.app */, ); name = Products; sourceTree = ""; }; 182B79E01FECDBAF005E0E81 /* YZAuthID */ = { isa = PBXGroup; children = ( 182B79FA1FECDCDB005E0E81 /* YZAuthID.h */, 182B79FB1FECDCDB005E0E81 /* YZAuthID.m */, ); path = YZAuthID; sourceTree = ""; }; 182B79F71FECDBD6005E0E81 /* YZAuthIDDemo */ = { isa = PBXGroup; children = ( 182B79E41FECDBAF005E0E81 /* ViewController.h */, 182B79E51FECDBAF005E0E81 /* ViewController.m */, 182B79E71FECDBAF005E0E81 /* Main.storyboard */, ); path = YZAuthIDDemo; sourceTree = ""; }; 182B79F91FECDBF6005E0E81 /* Supporting Files */ = { isa = PBXGroup; children = ( 182B79E11FECDBAF005E0E81 /* AppDelegate.h */, 182B79E21FECDBAF005E0E81 /* AppDelegate.m */, 182B79EA1FECDBAF005E0E81 /* Assets.xcassets */, 182B79EC1FECDBAF005E0E81 /* LaunchScreen.storyboard */, 182B79EF1FECDBAF005E0E81 /* Info.plist */, 182B79F01FECDBAF005E0E81 /* main.m */, 182B79FD1FECEE5A005E0E81 /* Images.xcassets */, ); path = "Supporting Files"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 182B79DD1FECDBAF005E0E81 /* YZAuthID */ = { isa = PBXNativeTarget; buildConfigurationList = 182B79F41FECDBAF005E0E81 /* Build configuration list for PBXNativeTarget "YZAuthID" */; buildPhases = ( 182B79DA1FECDBAF005E0E81 /* Sources */, 182B79DB1FECDBAF005E0E81 /* Frameworks */, 182B79DC1FECDBAF005E0E81 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = YZAuthID; productName = YZAuthID; productReference = 182B79DE1FECDBAF005E0E81 /* YZAuthID.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 182B79D61FECDBAF005E0E81 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0920; ORGANIZATIONNAME = Yanzheng; TargetAttributes = { 182B79DD1FECDBAF005E0E81 = { CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = 182B79D91FECDBAF005E0E81 /* Build configuration list for PBXProject "YZAuthID" */; compatibilityVersion = "Xcode 8.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 182B79D51FECDBAF005E0E81; productRefGroup = 182B79DF1FECDBAF005E0E81 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 182B79DD1FECDBAF005E0E81 /* YZAuthID */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 182B79DC1FECDBAF005E0E81 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 182B79EE1FECDBAF005E0E81 /* LaunchScreen.storyboard in Resources */, 182B79FE1FECEE5A005E0E81 /* Images.xcassets in Resources */, 182B79EB1FECDBAF005E0E81 /* Assets.xcassets in Resources */, 182B79E91FECDBAF005E0E81 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 182B79DA1FECDBAF005E0E81 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 182B79E61FECDBAF005E0E81 /* ViewController.m in Sources */, 182B79F11FECDBAF005E0E81 /* main.m in Sources */, 182B79E31FECDBAF005E0E81 /* AppDelegate.m in Sources */, 182B79FC1FECDCDB005E0E81 /* YZAuthID.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 182B79E71FECDBAF005E0E81 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 182B79E81FECDBAF005E0E81 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 182B79EC1FECDBAF005E0E81 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 182B79ED1FECDBAF005E0E81 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 182B79F21FECDBAF005E0E81 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; }; 182B79F31FECDBAF005E0E81 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; name = Release; }; 182B79F51FECDBAF005E0E81 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = YPP9C225DR; INFOPLIST_FILE = "$(SRCROOT)/Supporting Files/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 2.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.yan.YZAuthID; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; 182B79F61FECDBAF005E0E81 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = YPP9C225DR; INFOPLIST_FILE = "$(SRCROOT)/Supporting Files/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 2.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.yan.YZAuthID; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 182B79D91FECDBAF005E0E81 /* Build configuration list for PBXProject "YZAuthID" */ = { isa = XCConfigurationList; buildConfigurations = ( 182B79F21FECDBAF005E0E81 /* Debug */, 182B79F31FECDBAF005E0E81 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 182B79F41FECDBAF005E0E81 /* Build configuration list for PBXNativeTarget "YZAuthID" */ = { isa = XCConfigurationList; buildConfigurations = ( 182B79F51FECDBAF005E0E81 /* Debug */, 182B79F61FECDBAF005E0E81 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 182B79D61FECDBAF005E0E81 /* Project object */; } ================================================ FILE: YZAuthID.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: YZAuthID.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: YZAuthIDDemo/Base.lproj/Main.storyboard ================================================ ================================================ FILE: YZAuthIDDemo/ViewController.h ================================================ /************************************************************ Class : ViewController.h Describe : YZAuthID 认证方法示例代码 Company : Micyo Author : Yanzheng Date : 2018-07-26 Version : 2.0 Declare : Copyright © 2018 Yanzheng. All rights reserved. ************************************************************/ #import @interface ViewController : UIViewController @end ================================================ FILE: YZAuthIDDemo/ViewController.m ================================================ /************************************************************ Class : ViewController.m Describe : YZAuthID 认证方法示例代码 Company : Micyo Author : Yanzheng Date : 2018-07-26 Version : 2.0 Declare : Copyright © 2018 Yanzheng. All rights reserved. ************************************************************/ #import "ViewController.h" #import "YZAuthID.h" #define iPhoneX (UIScreen.mainScreen.bounds.size.width == 375.f && UIScreen.mainScreen.bounds.size.height == 812.f) @interface ViewController () @property (nonatomic, strong) UILabel *hintLabel; // 提示标题 @property (nonatomic, strong) UIImageView *imageView; // 图标 @property (nonatomic, strong) UIButton *actionBtn; // 按钮 @property (nonatomic, copy) NSString *authImage; // 认证图标名 @property (nonatomic, copy) NSString *authName; // 认证名称 @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.view.backgroundColor = UIColor.whiteColor; [self initialize]; } #pragma mark - 初始化方法 - (void)initialize { // 设置值 if(iPhoneX){ self.authImage = @"auth_face"; self.authName = @"面容"; }else{ self.authImage = @"auth_finger"; self.authName = @"指纹"; } // 添加组件 [self.view addSubview:self.hintLabel]; [self.view addSubview:self.imageView]; [self.view addSubview:self.actionBtn]; // 开始认证 [self authVerification]; } #pragma mark - 懒加载各组件 - (UILabel *)hintLabel { if(!_hintLabel){ _hintLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 160, self.view.frame.size.width, 60)]; _hintLabel.font = [UIFont systemFontOfSize:22.f]; _hintLabel.textAlignment = NSTextAlignmentCenter; _hintLabel.numberOfLines = 0; _hintLabel.text = [NSString stringWithFormat:@"YZAuth\n验证%@以进行登录", self.authName]; } return _hintLabel; } - (UIImageView *)imageView { if(!_imageView){ _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2 - 35, self.hintLabel.frame.origin.y + 130, 70, 70)]; _imageView.image = [UIImage imageNamed:self.authImage]; } return _imageView; } - (UIButton *)actionBtn { if(!_actionBtn){ _actionBtn = [UIButton buttonWithType:UIButtonTypeSystem]; _actionBtn.frame = CGRectMake(60, self.imageView.frame.origin.y + 190, self.view.frame.size.width - 120, 40); [_actionBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; _actionBtn.titleLabel.font = [UIFont systemFontOfSize:18.f]; [_actionBtn setTitle:[NSString stringWithFormat:@"点击验证%@", self.authName] forState:UIControlStateNormal]; [_actionBtn setBackgroundColor:[UIColor colorWithRed:123/255.f green:188/255.f blue:231/255.f alpha:1]]; _actionBtn.layer.cornerRadius = 5.f; _actionBtn.layer.masksToBounds = YES; [_actionBtn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside]; } return _actionBtn; } #pragma mark - 按钮点击事件 - (void)btnClicked:(UIButton *)sender { // 唤起指纹、面容ID验证 [self authVerification]; } #pragma mark - 验证TouchID/FaceID - (void)authVerification { YZAuthID *authID = [[YZAuthID alloc] init]; [authID yz_showAuthIDWithDescribe:nil block:^(YZAuthIDState state, NSError *error) { if (state == YZAuthIDStateNotSupport) { // 不支持TouchID/FaceID NSLog(@"对不起,当前设备不支持指纹/面容ID"); } else if(state == YZAuthIDStateFail) { // 认证失败 NSLog(@"指纹/面容ID不正确,认证失败"); } else if(state == YZAuthIDStateTouchIDLockout) { // 多次错误,已被锁定 NSLog(@"多次错误,指纹/面容ID已被锁定,请到手机解锁界面输入密码"); } else if (state == YZAuthIDStateSuccess) { // TouchID/FaceID验证成功 NSLog(@"认证成功!"); } }]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end ================================================ FILE: archive.sh ================================================ #!/bin/bash # 打包脚本使用说明: # 1.修改:yz_cocopods、yz_project、yz_scheme参数 # 2.执行:./archive.sh 默认打 Debug 包 # 3.执行:./archive.sh Release 打 Release 包 # 用Cocopods管理的.xcworkspace项目,赋值true;用Xcode默认创建的.xcodeproj,赋值false yz_cocopods=true # 工程名称(project的名称) yz_project=YZAuthID # scheme名称(也就是工程的target名称) yz_scheme=YZAuthID # Debug Release if [ -z $1 ]; then yz_configuration=Debug else yz_configuration=$1 fi # method,打包的方式(方式分别为 development, ad-hoc, app-store, enterprise) yz_method=development # 日期时间 yz_date=`date +%Y%m%d_%H%M%S` # 获取当前脚本所在目录 yz_script_path=$( cd $( dirname $0 ) && pwd ) # 工程目录 yz_project_path=$yz_script_path # 指定输出导出文件夹路径 yz_export_path=$yz_project_path/package/$yz_date # 指定输出归档文件路径 yz_export_archive=$yz_export_path/$yz_scheme.xcarchive # 指定输出ipa名称 yz_export_ipa=$yz_export_path/$yz_scheme.ipa # 指定导出ipa包需要用到的plist配置文件的路径 yz_export_options_plist=$yz_project_path/ExportOptions.plist # 下面两个参数只是在手动指定Pofile文件的时候用到,如果使用Xcode自动管理Profile,直接留空就好 # (跟method对应的)mobileprovision文件名,需要先双击安装.mobileprovision文件.手动管理Profile时必填 yz_mobileprovision_name="" # 项目的bundleID,手动管理Profile时必填 yz_bundle_identifier="" # 输出参数 echo --------------------脚本配置参数检查-------------------- echo yz_cocopods=$yz_cocopods echo yz_project=$yz_project echo yz_scheme=$yz_scheme echo yz_configuration=$yz_configuration echo yz_method=$yz_method echo yz_date=$yz_date echo yz_script_path=$yz_script_path echo yz_project_path=$yz_project_path echo yz_export_path=$yz_export_path echo yz_export_archive=$yz_export_archive echo yz_export_ipa=$yz_export_ipa echo yz_export_options_plist=$yz_export_options_plist if [[ "Debug" != $yz_configuration ]] && [[ "Release" != $yz_configuration ]]; then echo "参数yz_configuration=${1}不正确,yz_configuration取值范围:Debug(默认)、Release" exit 1 fi # 开发打包 echo --------------------自动打包脚本执行-------------------- # 进入项目工程目录 cd $yz_project_path # 指定输出文件目录不存在则创建 if [ -d $yz_export_path ] ; then echo $yz_export_path else mkdir -pv $yz_export_path fi # 判断是Cocoapods还是Xcode项目 if $yz_cocoapods ; then echo -------------------Cocoapods 项目打包------------------- # pods 添加 pod install # 打包脚本执行 xcodebuild archive \ -workspace $yz_project.xcworkspace \ -scheme $yz_scheme \ -configuration $yz_configuration \ -archivePath $yz_export_archive \ clean \ build else echo ---------------------Xcode 项目打包--------------------- xcodebuild archive \ -project $yz_project.xcodeproj \ -scheme $yz_scheme \ -configuration $yz_configuration \ -archivePath $yz_export_archive \ clean \ build fi # 检查构建是否成功 if [ -d $yz_export_archive ] ; then echo "项目构建成功,开始导出 ipa 文件🚀🚀🚀" else echo "项目构建失败😢😢😢" exit 1 fi # 先删除yz_export_options_plist文件 if [ -f $yz_export_options_plist ] ; then rm -rf $yz_export_options_plist fi # 根据参数生成export_options_plist文件 /usr/libexec/PlistBuddy -c "Add :method String ${yz_method}" $yz_export_options_plist /usr/libexec/PlistBuddy -c "Add :provisioningProfiles:" $yz_export_options_plist /usr/libexec/PlistBuddy -c "Add :provisioningProfiles:${yz_bundle_identifier} String ${yz_mobileprovision_name}" $yz_export_options_plist # 导出ipa文件 xcodebuild -exportArchive \ -archivePath $yz_export_archive \ -exportPath $yz_export_path \ -exportOptionsPlist $yz_export_options_plist \ -allowProvisioningUpdates # 检查ipa文件是否存在 if [ -f $yz_export_ipa ] ; then echo "导出 ipa 包成功🎉🎉🎉" open $yz_export_path else echo "导出 ipa 包失败😢😢😢" exit 1 fi # 删除 yz_export_options_plist 文件(中间文件) if [ -f $yz_export_options_plist ] ; then rm -f $yz_export_options_plist fi # 输出打包总用时 echo "使用脚本打包总耗时:${SECONDS}s"