├── .gitattributes ├── DocumentPicker ├── DocumentPicker │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── add_new.imageset │ │ │ ├── add_new.png │ │ │ └── Contents.json │ │ ├── image_placeholder.imageset │ │ │ ├── word.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── wordstore_1024pt.png │ │ │ ├── wordiPhoneApp_60pt@2x.png │ │ │ ├── wordiPhoneApp_60pt@3x.png │ │ │ ├── wordiPhoneNotification_20pt@2x.png │ │ │ ├── wordiPhoneNotification_20pt@3x.png │ │ │ ├── wordiPhoneSpootlight5_29pt@2x.png │ │ │ ├── wordiPhoneSpootlight5_29pt@3x.png │ │ │ ├── wordiPhoneSpootlight7_40pt@2x.png │ │ │ ├── wordiPhoneSpootlight7_40pt@3x.png │ │ │ └── Contents.json │ ├── View │ │ ├── NKOtherFilesModel.m │ │ ├── NKOtherFilesModel.h │ │ ├── OtherFilesViewCell.h │ │ ├── OtherFilesViewCell.m │ │ ├── UIActionSheet+Blocks.h │ │ └── UIActionSheet+Blocks.m │ ├── ViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── DocumentTool │ │ ├── NKSeleDocumentTool.h │ │ └── NKSeleDocumentTool.m │ ├── Info.plist │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ ├── AppDelegate.m │ └── ViewController.m ├── DocumentPicker.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── niekuan.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── xcuserdata │ │ └── niekuan.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── project.pbxproj ├── DocumentPickerTests │ ├── Info.plist │ └── DocumentPickerTests.m └── DocumentPickerUITests │ ├── Info.plist │ └── DocumentPickerUITests.m └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/add_new.imageset/add_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/add_new.imageset/add_new.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/image_placeholder.imageset/word.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/image_placeholder.imageset/word.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordstore_1024pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordstore_1024pt.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneApp_60pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneApp_60pt@2x.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneApp_60pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneApp_60pt@3x.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneNotification_20pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneNotification_20pt@2x.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneNotification_20pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneNotification_20pt@3x.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneSpootlight5_29pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneSpootlight5_29pt@2x.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneSpootlight5_29pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneSpootlight5_29pt@3x.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneSpootlight7_40pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneSpootlight7_40pt@2x.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneSpootlight7_40pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/wordiPhoneSpootlight7_40pt@3x.png -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker.xcodeproj/project.xcworkspace/xcuserdata/niekuan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NK-iOS/NKDocumentPickerViewController/HEAD/DocumentPicker/DocumentPicker.xcodeproj/project.xcworkspace/xcuserdata/niekuan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/View/NKOtherFilesModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // NKOtherFilesModel.m 3 | // DocumentPicker 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import "NKOtherFilesModel.h" 10 | 11 | @implementation NKOtherFilesModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // DocumentPicker 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DocumentPicker 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DocumentPicker 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/add_new.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "add_new.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/image_placeholder.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "word.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/View/NKOtherFilesModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // NKOtherFilesModel.h 3 | // DocumentPicker 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NKOtherFilesModel : NSObject 12 | @property (nonatomic, strong) NSString *filePath; 13 | 14 | @property (nonatomic, strong) NSString *fileName; 15 | 16 | @property (nonatomic, strong) NSString *iconName; 17 | @end 18 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker.xcodeproj/xcuserdata/niekuan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DocumentPicker.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/View/OtherFilesViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // OtherFilesViewCell.h 3 | // DocumentPicker 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NKOtherFilesModel.h" 11 | 12 | @interface OtherFilesViewCell : UICollectionViewCell 13 | @property (nonatomic, strong) NKOtherFilesModel *model; 14 | 15 | @property (nonatomic, strong) UIImageView *imgView; 16 | @property (nonatomic, strong) UILabel *titleLab; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPickerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPickerUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/DocumentTool/NKSeleDocumentTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // NKSeleDocumentTool.h 3 | // Personal 4 | // 5 | // Created by 聂宽 on 2018/6/21. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | typedef void(^SeleDocumentFinish)(NSArray *urls); 14 | 15 | @interface NKSeleDocumentTool : NSObject 16 | + (NKSeleDocumentTool *)shareDocumentTool; 17 | 18 | - (void)seleDocumentWithDocumentTypes:(NSArray *)allowedUTIs Mode:(UIDocumentPickerMode)mode controller:(UIViewController *)vc finishBlock:(SeleDocumentFinish)seleFinish; 19 | /* 20 | Thanks for your review! 21 | 2.5.15: The "从“文件”上传" is select items from the Files app and the user's iCloud documents. 22 | I ask apple's technical support for the solution. 23 | */ 24 | @end 25 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPickerTests/DocumentPickerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DocumentPickerTests.m 3 | // DocumentPickerTests 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DocumentPickerTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation DocumentPickerTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPickerUITests/DocumentPickerUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DocumentPickerUITests.m 3 | // DocumentPickerUITests 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DocumentPickerUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation DocumentPickerUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NKDocumentPickerViewController 2 | 3 | ## 一行代码实现从手机上传文件到APP 4 | * Guideline 2.5.15 - Performance - Software Requirements 5 | * 由于最近项目审核遇到的一些问题,一直不理解苹果爸爸到底是让我怎么修改,,,最后才明白苹果的新规,遇到类似问题的可以参考。 6 | * 利用UIDocumentPickerViewController从手机上传文件到app!有时候会有这么一些需求,需要用户上传自己的一些xml,doc,pdf文档.可是iOS上并没有直观的文件管理系统.这时候Document Picker就可以帮助我们访问iCould,dropBox等应用中的文件.然后进行相关操作. 7 | # 上线APP: 8 | 9 | 我的超级文件 10 | 11 | # 方法调用: 12 | ```objc 13 | [[NKSeleDocumentTool shareDocumentTool] seleDocumentWithDocumentTypes:@[@"public.data"] Mode:UIDocumentPickerModeImport controller:self finishBlock:^(NSArray *urls) { 14 | NSURL *fileUrl = urls.firstObject; 15 | // 选择的文件数据 16 | NSData *fileData = [NSData dataWithContentsOfURL:fileUrl]; 17 | }]; 18 | ``` 19 | * DocumentTypes参数可以筛选自己需要的文件类型,可以参考下边这张图: 20 | 21 | 22 | # 效果预览: 23 | 24 | 一行代码实现文件选择,简洁方便 25 | 26 | # 其他: 27 | * 自由开发者交流群:811483008 28 | * 简书 29 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/View/OtherFilesViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // OtherFilesViewCell.m 3 | // DocumentPicker 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import "OtherFilesViewCell.h" 10 | 11 | @implementation OtherFilesViewCell 12 | - (instancetype)initWithFrame:(CGRect)frame 13 | { 14 | if (self = [super initWithFrame:frame]) { 15 | self.backgroundColor = [UIColor whiteColor]; 16 | _imgView = [[UIImageView alloc] init]; 17 | _imgView.contentMode = UIViewContentModeScaleAspectFit; 18 | _imgView.image = [UIImage imageNamed:@"image_placeholder"]; 19 | _imgView.clipsToBounds = YES; 20 | [self addSubview:_imgView]; 21 | _imgView.frame = CGRectMake(0, 2, self.frame.size.width, self.frame.size.height - 42); 22 | 23 | _titleLab = [[UILabel alloc] init]; 24 | _titleLab.textAlignment = NSTextAlignmentCenter; 25 | _titleLab.numberOfLines = 2; 26 | _titleLab.font = [UIFont systemFontOfSize:14]; 27 | _titleLab.textColor = [UIColor lightGrayColor]; 28 | [self addSubview:_titleLab]; 29 | _titleLab.frame = CGRectMake(5, CGRectGetMaxY(_imgView.frame) + 3, self.frame.size.width - 10, self.frame.size.height - (CGRectGetMaxY(_imgView.frame) + 3)); 30 | } 31 | return self; 32 | } 33 | 34 | - (void)setModel:(NKOtherFilesModel *)model 35 | { 36 | _model = model; 37 | _titleLab.text = model.fileName; 38 | } 39 | @end 40 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "wordiPhoneNotification_20pt@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "wordiPhoneNotification_20pt@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "wordiPhoneSpootlight5_29pt@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "wordiPhoneSpootlight5_29pt@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "wordiPhoneSpootlight7_40pt@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "wordiPhoneSpootlight7_40pt@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "wordiPhoneApp_60pt@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "wordiPhoneApp_60pt@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "1024x1024", 53 | "idiom" : "ios-marketing", 54 | "filename" : "wordstore_1024pt.png", 55 | "scale" : "1x" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/DocumentTool/NKSeleDocumentTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // NKSeleDocumentTool.m 3 | // Personal 4 | // 5 | // Created by 聂宽 on 2018/6/21. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import "NKSeleDocumentTool.h" 10 | 11 | @interface NKSeleDocumentTool() 12 | @property (nonatomic, copy) SeleDocumentFinish seleFinish; 13 | @property (nonatomic, strong) UIViewController *vc; 14 | @end 15 | 16 | @implementation NKSeleDocumentTool 17 | + (NKSeleDocumentTool *)shareDocumentTool 18 | { 19 | static NKSeleDocumentTool *instance = nil; 20 | static dispatch_once_t onceToken; 21 | dispatch_once(&onceToken, ^{ 22 | instance = [[NKSeleDocumentTool alloc] init]; 23 | }); 24 | return instance; 25 | } 26 | 27 | - (void)seleDocumentWithDocumentTypes:(NSArray *)allowedUTIs Mode:(UIDocumentPickerMode)mode controller:(UIViewController *)vc finishBlock:(SeleDocumentFinish)seleFinish 28 | { 29 | // @[@"public.3gpp"] 30 | UIDocumentPickerViewController *picker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:allowedUTIs inMode:mode]; 31 | picker.delegate = self; 32 | _vc = vc; 33 | _seleFinish = seleFinish; 34 | [vc presentViewController:picker animated:YES completion:nil]; 35 | } 36 | 37 | #pragma mark - UIDocumentPickerDelegate 38 | - (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray *)urls 39 | { 40 | if (self.seleFinish) { 41 | self.seleFinish(urls); 42 | } 43 | [controller dismissViewControllerAnimated:YES completion:^{ 44 | 45 | }]; 46 | } 47 | @end 48 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DocumentPicker 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | 20 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 21 | UINavigationController *nag = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]]; 22 | self.window.rootViewController = nag; 23 | [self.window makeKeyAndVisible]; 24 | 25 | return YES; 26 | } 27 | 28 | 29 | - (void)applicationWillResignActive:(UIApplication *)application { 30 | // 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. 31 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 32 | } 33 | 34 | 35 | - (void)applicationDidEnterBackground:(UIApplication *)application { 36 | // 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. 37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 38 | } 39 | 40 | 41 | - (void)applicationWillEnterForeground:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationDidBecomeActive:(UIApplication *)application { 47 | // 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. 48 | } 49 | 50 | 51 | - (void)applicationWillTerminate:(UIApplication *)application { 52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 53 | } 54 | 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/View/UIActionSheet+Blocks.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIActionSheet+Blocks.h 3 | // UIActionSheetBlocks 4 | // 5 | // Created by Ryan Maxwell on 31/08/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Maxwell 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import 30 | 31 | typedef void (^UIActionSheetBlock) (UIActionSheet * __nonnull actionSheet); 32 | typedef void (^UIActionSheetCompletionBlock) (UIActionSheet * __nonnull actionSheet, NSInteger buttonIndex); 33 | 34 | @interface UIActionSheet (Blocks) 35 | 36 | + (nonnull instancetype)showFromTabBar:(nonnull UITabBar *)tabBar 37 | withTitle:(nullable NSString *)title 38 | cancelButtonTitle:(nullable NSString *)cancelButtonTitle 39 | destructiveButtonTitle:(nullable NSString *)destructiveButtonTitle 40 | otherButtonTitles:(nullable NSArray *)otherButtonTitles 41 | tapBlock:(nullable UIActionSheetCompletionBlock)tapBlock; 42 | 43 | + (nonnull instancetype)showFromToolbar:(nonnull UIToolbar *)toolbar 44 | withTitle:(nullable NSString *)title 45 | cancelButtonTitle:(nullable NSString *)cancelButtonTitle 46 | destructiveButtonTitle:(nullable NSString *)destructiveButtonTitle 47 | otherButtonTitles:(nullable NSArray *)otherButtonTitles 48 | tapBlock:(nullable UIActionSheetCompletionBlock)tapBlock; 49 | 50 | + (nonnull instancetype)showInView:(nonnull UIView *)view 51 | withTitle:(nullable NSString *)title 52 | cancelButtonTitle:(nullable NSString *)cancelButtonTitle 53 | destructiveButtonTitle:(nullable NSString *)destructiveButtonTitle 54 | otherButtonTitles:(nullable NSArray *)otherButtonTitles 55 | tapBlock:(nullable UIActionSheetCompletionBlock)tapBlock; 56 | 57 | + (nonnull instancetype)showFromBarButtonItem:(nonnull UIBarButtonItem *)barButtonItem 58 | animated:(BOOL)animated 59 | withTitle:(nullable NSString *)title 60 | cancelButtonTitle:(nullable NSString *)cancelButtonTitle 61 | destructiveButtonTitle:(nullable NSString *)destructiveButtonTitle 62 | otherButtonTitles:(nullable NSArray *)otherButtonTitles 63 | tapBlock:(nullable UIActionSheetCompletionBlock)tapBlock; 64 | 65 | + (nonnull instancetype)showFromRect:(CGRect)rect 66 | inView:(nonnull UIView *)view 67 | animated:(BOOL)animated 68 | withTitle:(nullable NSString *)title 69 | cancelButtonTitle:(nullable NSString *)cancelButtonTitle 70 | destructiveButtonTitle:(nullable NSString *)destructiveButtonTitle 71 | otherButtonTitles:(nullable NSArray *)otherButtonTitles 72 | tapBlock:(nullable UIActionSheetCompletionBlock)tapBlock; 73 | 74 | @property (copy, nonatomic, nullable) UIActionSheetCompletionBlock tapBlock; 75 | @property (copy, nonatomic, nullable) UIActionSheetCompletionBlock willDismissBlock; 76 | @property (copy, nonatomic, nullable) UIActionSheetCompletionBlock didDismissBlock; 77 | 78 | @property (copy, nonatomic, nullable) UIActionSheetBlock willPresentBlock; 79 | @property (copy, nonatomic, nullable) UIActionSheetBlock didPresentBlock; 80 | @property (copy, nonatomic, nullable) UIActionSheetBlock cancelBlock; 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DocumentPicker 4 | // 5 | // Created by 聂宽 on 2018/6/27. 6 | // Copyright © 2018年 聂宽. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "NKSeleDocumentTool.h" 11 | #import "OtherFilesViewCell.h" 12 | #import 13 | #import "UIActionSheet+Blocks.h" 14 | 15 | #define screenW [[UIScreen mainScreen] bounds].size.width 16 | #define screenH [[UIScreen mainScreen] bounds].size.height 17 | 18 | #define NKColorWithRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0] 19 | 20 | @interface ViewController () 21 | @property (nonatomic, strong) UICollectionView *collectionView; 22 | @property (nonatomic, strong) NSMutableArray *dataArr; 23 | 24 | @property (nonatomic, strong) NKOtherFilesModel *seleFileM; 25 | 26 | @end 27 | // cell 28 | static NSString *OtherFilesViewCellID = @"OtherFilesViewCell"; 29 | 30 | @implementation ViewController 31 | 32 | - (NSMutableArray *)dataArr 33 | { 34 | if (_dataArr == nil) { 35 | _dataArr = [NSMutableArray array]; 36 | 37 | NSString *documentPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"OtherFiles"]; 38 | NSFileManager *fileManager = [NSFileManager defaultManager]; 39 | NSArray *files = [fileManager contentsOfDirectoryAtPath:documentPath error:nil]; 40 | for (NSString *fileName in files) { 41 | NSString *filePath = [documentPath stringByAppendingPathComponent:fileName]; 42 | NKOtherFilesModel *model = [[NKOtherFilesModel alloc] init]; 43 | model.fileName = fileName; 44 | model.filePath = filePath; 45 | [_dataArr addObject:model]; 46 | } 47 | } 48 | return _dataArr; 49 | } 50 | 51 | - (UICollectionView *)collectionView 52 | { 53 | if (_collectionView == nil) { 54 | UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 55 | layout.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5); 56 | _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height - 44) collectionViewLayout:layout]; 57 | _collectionView.delegate = self; 58 | _collectionView.dataSource = self; 59 | [_collectionView registerClass:[OtherFilesViewCell class] forCellWithReuseIdentifier:OtherFilesViewCellID]; 60 | [self.view addSubview:_collectionView]; 61 | } 62 | return _collectionView; 63 | } 64 | 65 | - (void)viewDidLoad { 66 | [super viewDidLoad]; 67 | self.title = @"选择文件"; 68 | self.view.backgroundColor = NKColorWithRGB(0xEFEFF4); 69 | self.collectionView.backgroundColor = self.view.backgroundColor; 70 | 71 | [self settingBottomView]; 72 | } 73 | 74 | - (void)settingBottomView 75 | { 76 | UIView *bottomView = [[UIView alloc] init]; 77 | bottomView.backgroundColor = [UIColor whiteColor]; 78 | bottomView.layer.borderWidth = 1; 79 | bottomView.layer.borderColor = NKColorWithRGB(0xEFEFF4).CGColor; 80 | [self.view addSubview:bottomView]; 81 | bottomView.frame = CGRectMake(0, self.view.frame.size.height - 44, screenW, 44); 82 | 83 | UIButton *addBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 84 | [addBtn setTitle:@"添加" forState:UIControlStateNormal]; 85 | [addBtn setTitleColor:NKColorWithRGB(0x323232) forState:UIControlStateNormal]; 86 | [addBtn setImage:[UIImage imageNamed:@"add_new"] forState:UIControlStateNormal]; 87 | addBtn.titleLabel.font = [UIFont systemFontOfSize:15]; 88 | addBtn.imageView.contentMode = UIViewContentModeScaleAspectFit; 89 | [addBtn addTarget:self action:@selector(addBtnAction) forControlEvents:UIControlEventTouchUpInside]; 90 | [bottomView addSubview:addBtn]; 91 | addBtn.frame = CGRectMake(0, 0, screenW, 44); 92 | } 93 | 94 | - (void)addBtnAction 95 | { 96 | [UIActionSheet showInView:self.view 97 | withTitle:@"打开文件" 98 | cancelButtonTitle:@"取消" 99 | destructiveButtonTitle:nil 100 | otherButtonTitles:@[@"从“文件”上传"] 101 | tapBlock:^(UIActionSheet *actionSheet, NSInteger buttonIndex) { 102 | if (buttonIndex == 0) { 103 | [[NKSeleDocumentTool shareDocumentTool] seleDocumentWithDocumentTypes:@[@"public.data"] Mode:UIDocumentPickerModeImport controller:self finishBlock:^(NSArray *urls) { 104 | NSURL *fileUrl = urls.firstObject; 105 | NSData *fileData = [NSData dataWithContentsOfURL:fileUrl]; 106 | NSString *fileName = [[[fileUrl absoluteString] componentsSeparatedByString:@"/"] lastObject]; 107 | NSString *documentPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"OtherFiles"]; 108 | NSString *newFilePath = [documentPath stringByAppendingPathComponent:fileName]; 109 | NSFileManager *fileManager = [NSFileManager defaultManager]; 110 | 111 | // 判断movie文件是否存在,如果不存在,就创建一个 112 | if (![fileManager fileExistsAtPath:documentPath]) { 113 | [fileManager createDirectoryAtPath:documentPath withIntermediateDirectories:YES attributes:nil error:nil]; 114 | } 115 | if ([fileManager createFileAtPath:newFilePath contents:fileData attributes:nil]) { 116 | _dataArr = nil; 117 | [self.collectionView reloadData]; 118 | }else 119 | { 120 | // 失败 121 | NSLog(@"保存失败!"); 122 | } 123 | }]; 124 | } 125 | }]; 126 | } 127 | 128 | #pragma mark - UICollectionViewDataSource 129 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 130 | { 131 | return self.dataArr.count; 132 | } 133 | 134 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 135 | { 136 | OtherFilesViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:OtherFilesViewCellID forIndexPath:indexPath]; 137 | NKOtherFilesModel *model = self.dataArr[indexPath.item]; 138 | cell.model = model; 139 | return cell; 140 | } 141 | 142 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 143 | { 144 | NKOtherFilesModel *model = self.dataArr[indexPath.item]; 145 | _seleFileM = model; 146 | [self QLPreviewingControllerLoad]; 147 | } 148 | 149 | #pragma mark - item宽高 150 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { 151 | CGFloat itemW = (screenW - (1 + 3)*5 ) /3 ; 152 | return CGSizeMake(itemW, itemW + 10); 153 | } 154 | 155 | #pragma mark - 156 | #pragma mark - X间距 157 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { 158 | return 5; 159 | } 160 | 161 | #pragma mark - Y间距 162 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section { 163 | return 5; 164 | } 165 | 166 | - (void)QLPreviewingControllerLoad 167 | { 168 | QLPreviewController *QLVC = [[QLPreviewController alloc] init]; 169 | QLVC.dataSource = self; 170 | [self presentViewController:QLVC animated:YES completion:^{ 171 | 172 | }]; 173 | } 174 | 175 | - (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller 176 | { 177 | return 1; 178 | } 179 | 180 | - (id)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index 181 | { 182 | NSURL *documentsDirectoryURL = [NSURL fileURLWithPath:self.seleFileM.filePath]; 183 | return documentsDirectoryURL; 184 | } 185 | 186 | - (void)viewWillAppear:(BOOL)animated 187 | { 188 | [super viewWillAppear:animated]; 189 | NSString *documentPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"OtherFiles"]; 190 | NSFileManager *fileManager = [NSFileManager defaultManager]; 191 | // 判断Image文件是否存在,如果不存在,就创建一个 192 | if (![fileManager fileExistsAtPath:documentPath]) { 193 | [fileManager createDirectoryAtPath:documentPath withIntermediateDirectories:YES attributes:nil error:nil]; 194 | } 195 | _dataArr = nil; 196 | [self.collectionView reloadData]; 197 | } 198 | @end 199 | 200 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker/View/UIActionSheet+Blocks.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIActionSheet+Blocks.m 3 | // UIActionSheetBlocks 4 | // 5 | // Created by Ryan Maxwell on 31/08/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Maxwell 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import "UIActionSheet+Blocks.h" 30 | 31 | #import 32 | 33 | static const void *UIActionSheetOriginalDelegateKey = &UIActionSheetOriginalDelegateKey; 34 | 35 | static const void *UIActionSheetTapBlockKey = &UIActionSheetTapBlockKey; 36 | static const void *UIActionSheetWillPresentBlockKey = &UIActionSheetWillPresentBlockKey; 37 | static const void *UIActionSheetDidPresentBlockKey = &UIActionSheetDidPresentBlockKey; 38 | static const void *UIActionSheetWillDismissBlockKey = &UIActionSheetWillDismissBlockKey; 39 | static const void *UIActionSheetDidDismissBlockKey = &UIActionSheetDidDismissBlockKey; 40 | static const void *UIActionSheetCancelBlockKey = &UIActionSheetCancelBlockKey; 41 | 42 | #define NSArrayObjectMaybeNil(__ARRAY__, __INDEX__) ((__INDEX__ >= [__ARRAY__ count]) ? nil : [__ARRAY__ objectAtIndex:__INDEX__]) 43 | // This is a hack to turn an array into a variable argument list. There is no good way to expand arrays into variable argument lists in Objective-C. This works by nil-terminating the list as soon as we overstep the bounds of the array. The obvious glitch is that we only support a finite number of buttons. 44 | #define NSArrayToVariableArgumentsList(__ARRAYNAME__) NSArrayObjectMaybeNil(__ARRAYNAME__, 0), NSArrayObjectMaybeNil(__ARRAYNAME__, 1), NSArrayObjectMaybeNil(__ARRAYNAME__, 2), NSArrayObjectMaybeNil(__ARRAYNAME__, 3), NSArrayObjectMaybeNil(__ARRAYNAME__, 4), NSArrayObjectMaybeNil(__ARRAYNAME__, 5), NSArrayObjectMaybeNil(__ARRAYNAME__, 6), NSArrayObjectMaybeNil(__ARRAYNAME__, 7), NSArrayObjectMaybeNil(__ARRAYNAME__, 8), NSArrayObjectMaybeNil(__ARRAYNAME__, 9), nil 45 | 46 | @implementation UIActionSheet (Blocks) 47 | 48 | + (instancetype)showFromTabBar:(UITabBar *)tabBar 49 | withTitle:(NSString *)title 50 | cancelButtonTitle:(NSString *)cancelButtonTitle 51 | destructiveButtonTitle:(NSString *)destructiveButtonTitle 52 | otherButtonTitles:(NSArray *)otherButtonTitles 53 | tapBlock:(UIActionSheetCompletionBlock)tapBlock { 54 | 55 | UIActionSheet *actionSheet = [[self alloc] initWithTitle:title 56 | delegate:nil 57 | cancelButtonTitle:cancelButtonTitle 58 | destructiveButtonTitle:destructiveButtonTitle 59 | otherButtonTitles:NSArrayToVariableArgumentsList(otherButtonTitles)]; 60 | 61 | if (tapBlock) { 62 | actionSheet.tapBlock = tapBlock; 63 | } 64 | 65 | [actionSheet showFromTabBar:tabBar]; 66 | 67 | #if !__has_feature(objc_arc) 68 | return [actionSheet autorelease]; 69 | #else 70 | return actionSheet; 71 | #endif 72 | } 73 | 74 | + (instancetype)showFromToolbar:(UIToolbar *)toolbar 75 | withTitle:(NSString *)title 76 | cancelButtonTitle:(NSString *)cancelButtonTitle 77 | destructiveButtonTitle:(NSString *)destructiveButtonTitle 78 | otherButtonTitles:(NSArray *)otherButtonTitles 79 | tapBlock:(UIActionSheetCompletionBlock)tapBlock { 80 | 81 | UIActionSheet *actionSheet = [[self alloc] initWithTitle:title 82 | delegate:nil 83 | cancelButtonTitle:cancelButtonTitle 84 | destructiveButtonTitle:destructiveButtonTitle 85 | otherButtonTitles:NSArrayToVariableArgumentsList(otherButtonTitles)]; 86 | 87 | if (tapBlock) { 88 | actionSheet.tapBlock = tapBlock; 89 | } 90 | 91 | [actionSheet showFromToolbar:toolbar]; 92 | 93 | #if !__has_feature(objc_arc) 94 | return [actionSheet autorelease]; 95 | #else 96 | return actionSheet; 97 | #endif 98 | } 99 | 100 | + (instancetype)showInView:(UIView *)view 101 | withTitle:(NSString *)title 102 | cancelButtonTitle:(NSString *)cancelButtonTitle 103 | destructiveButtonTitle:(NSString *)destructiveButtonTitle 104 | otherButtonTitles:(NSArray *)otherButtonTitles 105 | tapBlock:(UIActionSheetCompletionBlock)tapBlock { 106 | 107 | UIActionSheet *actionSheet = [[self alloc] initWithTitle:title 108 | delegate:nil 109 | cancelButtonTitle:cancelButtonTitle 110 | destructiveButtonTitle:destructiveButtonTitle 111 | otherButtonTitles:NSArrayToVariableArgumentsList(otherButtonTitles)]; 112 | 113 | if (tapBlock) { 114 | actionSheet.tapBlock = tapBlock; 115 | } 116 | 117 | [actionSheet showInView:view]; 118 | 119 | #if !__has_feature(objc_arc) 120 | return [actionSheet autorelease]; 121 | #else 122 | return actionSheet; 123 | #endif 124 | } 125 | 126 | + (instancetype)showFromBarButtonItem:(UIBarButtonItem *)barButtonItem 127 | animated:(BOOL)animated 128 | withTitle:(NSString *)title 129 | cancelButtonTitle:(NSString *)cancelButtonTitle 130 | destructiveButtonTitle:(NSString *)destructiveButtonTitle 131 | otherButtonTitles:(NSArray *)otherButtonTitles 132 | tapBlock:(UIActionSheetCompletionBlock)tapBlock { 133 | 134 | UIActionSheet *actionSheet = [[self alloc] initWithTitle:title 135 | delegate:nil 136 | cancelButtonTitle:cancelButtonTitle 137 | destructiveButtonTitle:destructiveButtonTitle 138 | otherButtonTitles:NSArrayToVariableArgumentsList(otherButtonTitles)]; 139 | 140 | if (tapBlock) { 141 | actionSheet.tapBlock = tapBlock; 142 | } 143 | 144 | [actionSheet showFromBarButtonItem:barButtonItem animated:animated]; 145 | 146 | #if !__has_feature(objc_arc) 147 | return [actionSheet autorelease]; 148 | #else 149 | return actionSheet; 150 | #endif 151 | } 152 | 153 | + (instancetype)showFromRect:(CGRect)rect 154 | inView:(UIView *)view 155 | animated:(BOOL)animated 156 | withTitle:(NSString *)title 157 | cancelButtonTitle:(NSString *)cancelButtonTitle 158 | destructiveButtonTitle:(NSString *)destructiveButtonTitle 159 | otherButtonTitles:(NSArray *)otherButtonTitles 160 | tapBlock:(UIActionSheetCompletionBlock)tapBlock { 161 | 162 | UIActionSheet *actionSheet = [[self alloc] initWithTitle:title 163 | delegate:nil 164 | cancelButtonTitle:cancelButtonTitle 165 | destructiveButtonTitle:destructiveButtonTitle 166 | otherButtonTitles:NSArrayToVariableArgumentsList(otherButtonTitles)]; 167 | 168 | if (tapBlock) { 169 | actionSheet.tapBlock = tapBlock; 170 | } 171 | 172 | [actionSheet showFromRect:rect inView:view animated:animated]; 173 | 174 | #if !__has_feature(objc_arc) 175 | return [actionSheet autorelease]; 176 | #else 177 | return actionSheet; 178 | #endif 179 | } 180 | 181 | #pragma mark - 182 | 183 | - (void)_checkActionSheetDelegate { 184 | if (self.delegate != (id)self) { 185 | objc_setAssociatedObject(self, UIActionSheetOriginalDelegateKey, self.delegate, OBJC_ASSOCIATION_ASSIGN); 186 | self.delegate = (id)self; 187 | } 188 | } 189 | 190 | - (UIActionSheetCompletionBlock)tapBlock { 191 | return objc_getAssociatedObject(self, UIActionSheetTapBlockKey); 192 | } 193 | 194 | - (void)setTapBlock:(UIActionSheetCompletionBlock)tapBlock { 195 | [self _checkActionSheetDelegate]; 196 | objc_setAssociatedObject(self, UIActionSheetTapBlockKey, tapBlock, OBJC_ASSOCIATION_COPY); 197 | } 198 | 199 | - (UIActionSheetCompletionBlock)willDismissBlock { 200 | return objc_getAssociatedObject(self, UIActionSheetWillDismissBlockKey); 201 | } 202 | 203 | - (void)setWillDismissBlock:(UIActionSheetCompletionBlock)willDismissBlock { 204 | [self _checkActionSheetDelegate]; 205 | objc_setAssociatedObject(self, UIActionSheetWillDismissBlockKey, willDismissBlock, OBJC_ASSOCIATION_COPY); 206 | } 207 | 208 | - (UIActionSheetCompletionBlock)didDismissBlock { 209 | return objc_getAssociatedObject(self, UIActionSheetDidDismissBlockKey); 210 | } 211 | 212 | - (void)setDidDismissBlock:(UIActionSheetCompletionBlock)didDismissBlock { 213 | [self _checkActionSheetDelegate]; 214 | objc_setAssociatedObject(self, UIActionSheetDidDismissBlockKey, didDismissBlock, OBJC_ASSOCIATION_COPY); 215 | } 216 | 217 | - (UIActionSheetBlock)willPresentBlock { 218 | return objc_getAssociatedObject(self, UIActionSheetWillPresentBlockKey); 219 | } 220 | 221 | - (void)setWillPresentBlock:(UIActionSheetBlock)willPresentBlock { 222 | [self _checkActionSheetDelegate]; 223 | objc_setAssociatedObject(self, UIActionSheetWillPresentBlockKey, willPresentBlock, OBJC_ASSOCIATION_COPY); 224 | } 225 | 226 | - (UIActionSheetBlock)didPresentBlock { 227 | return objc_getAssociatedObject(self, UIActionSheetDidPresentBlockKey); 228 | } 229 | 230 | - (void)setDidPresentBlock:(UIActionSheetBlock)didPresentBlock { 231 | [self _checkActionSheetDelegate]; 232 | objc_setAssociatedObject(self, UIActionSheetDidPresentBlockKey, didPresentBlock, OBJC_ASSOCIATION_COPY); 233 | } 234 | 235 | - (UIActionSheetBlock)cancelBlock { 236 | return objc_getAssociatedObject(self, UIActionSheetCancelBlockKey); 237 | } 238 | 239 | - (void)setCancelBlock:(UIActionSheetBlock)cancelBlock { 240 | [self _checkActionSheetDelegate]; 241 | objc_setAssociatedObject(self, UIActionSheetCancelBlockKey, cancelBlock, OBJC_ASSOCIATION_COPY); 242 | } 243 | 244 | #pragma mark - UIActionSheetDelegate 245 | 246 | - (void)willPresentActionSheet:(UIActionSheet *)actionSheet { 247 | UIActionSheetBlock completion = actionSheet.willPresentBlock; 248 | 249 | if (completion) { 250 | completion(actionSheet); 251 | } 252 | 253 | id originalDelegate = objc_getAssociatedObject(self, UIActionSheetOriginalDelegateKey); 254 | if (originalDelegate && [originalDelegate respondsToSelector:@selector(willPresentActionSheet:)]) { 255 | [originalDelegate willPresentActionSheet:actionSheet]; 256 | } 257 | } 258 | 259 | - (void)didPresentActionSheet:(UIActionSheet *)actionSheet { 260 | UIActionSheetBlock completion = actionSheet.didPresentBlock; 261 | 262 | if (completion) { 263 | completion(actionSheet); 264 | } 265 | 266 | id originalDelegate = objc_getAssociatedObject(self, UIActionSheetOriginalDelegateKey); 267 | if (originalDelegate && [originalDelegate respondsToSelector:@selector(didPresentActionSheet:)]) { 268 | [originalDelegate didPresentActionSheet:actionSheet]; 269 | } 270 | } 271 | 272 | - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { 273 | UIActionSheetCompletionBlock completion = actionSheet.tapBlock; 274 | 275 | if (completion) { 276 | completion(actionSheet, buttonIndex); 277 | } 278 | 279 | id originalDelegate = objc_getAssociatedObject(self, UIActionSheetOriginalDelegateKey); 280 | if (originalDelegate && [originalDelegate respondsToSelector:@selector(actionSheet:clickedButtonAtIndex:)]) { 281 | [originalDelegate actionSheet:actionSheet clickedButtonAtIndex:buttonIndex]; 282 | } 283 | } 284 | 285 | - (void)actionSheetCancel:(UIActionSheet *)actionSheet { 286 | UIActionSheetBlock completion = actionSheet.cancelBlock; 287 | 288 | if (completion) { 289 | completion(actionSheet); 290 | } 291 | 292 | id originalDelegate = objc_getAssociatedObject(self, UIActionSheetOriginalDelegateKey); 293 | if (originalDelegate && [originalDelegate respondsToSelector:@selector(actionSheetCancel:)]) { 294 | [originalDelegate actionSheetCancel:actionSheet]; 295 | } 296 | } 297 | 298 | - (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex { 299 | UIActionSheetCompletionBlock completion = actionSheet.willDismissBlock; 300 | 301 | if (completion) { 302 | completion(actionSheet, buttonIndex); 303 | } 304 | 305 | id originalDelegate = objc_getAssociatedObject(self, UIActionSheetOriginalDelegateKey); 306 | if (originalDelegate && [originalDelegate respondsToSelector:@selector(actionSheet:willDismissWithButtonIndex:)]) { 307 | [originalDelegate actionSheet:actionSheet willDismissWithButtonIndex:buttonIndex]; 308 | } 309 | } 310 | 311 | - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { 312 | UIActionSheetCompletionBlock completion = actionSheet.didDismissBlock; 313 | 314 | if (completion) { 315 | completion(actionSheet, buttonIndex); 316 | } 317 | 318 | id originalDelegate = objc_getAssociatedObject(self, UIActionSheetOriginalDelegateKey); 319 | if (originalDelegate && [originalDelegate respondsToSelector:@selector(actionSheet:didDismissWithButtonIndex:)]) { 320 | [originalDelegate actionSheet:actionSheet didDismissWithButtonIndex:buttonIndex]; 321 | } 322 | } 323 | 324 | @end 325 | -------------------------------------------------------------------------------- /DocumentPicker/DocumentPicker.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1B24139B20E3C2B100FBD773 /* UIActionSheet+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B24139920E3C2B100FBD773 /* UIActionSheet+Blocks.m */; }; 11 | 1B61EF9E20E38B1C0051A489 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B61EF9D20E38B1C0051A489 /* AppDelegate.m */; }; 12 | 1B61EFA120E38B1C0051A489 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B61EFA020E38B1C0051A489 /* ViewController.m */; }; 13 | 1B61EFA420E38B1C0051A489 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1B61EFA220E38B1C0051A489 /* Main.storyboard */; }; 14 | 1B61EFA620E38B1C0051A489 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1B61EFA520E38B1C0051A489 /* Assets.xcassets */; }; 15 | 1B61EFA920E38B1C0051A489 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1B61EFA720E38B1C0051A489 /* LaunchScreen.storyboard */; }; 16 | 1B61EFAC20E38B1C0051A489 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B61EFAB20E38B1C0051A489 /* main.m */; }; 17 | 1B61EFB620E38B1C0051A489 /* DocumentPickerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B61EFB520E38B1C0051A489 /* DocumentPickerTests.m */; }; 18 | 1B61EFC120E38B1C0051A489 /* DocumentPickerUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B61EFC020E38B1C0051A489 /* DocumentPickerUITests.m */; }; 19 | 1B61EFD120E38BD20051A489 /* NKSeleDocumentTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B61EFCF20E38BD20051A489 /* NKSeleDocumentTool.m */; }; 20 | 1B61EFD520E390E80051A489 /* OtherFilesViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B61EFD420E390E80051A489 /* OtherFilesViewCell.m */; }; 21 | 1B61EFD820E393510051A489 /* NKOtherFilesModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B61EFD720E393510051A489 /* NKOtherFilesModel.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | 1B61EFB220E38B1C0051A489 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = 1B61EF9120E38B1C0051A489 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = 1B61EF9820E38B1C0051A489; 30 | remoteInfo = DocumentPicker; 31 | }; 32 | 1B61EFBD20E38B1C0051A489 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 1B61EF9120E38B1C0051A489 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 1B61EF9820E38B1C0051A489; 37 | remoteInfo = DocumentPicker; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | 1B24139920E3C2B100FBD773 /* UIActionSheet+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIActionSheet+Blocks.m"; sourceTree = ""; }; 43 | 1B24139A20E3C2B100FBD773 /* UIActionSheet+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIActionSheet+Blocks.h"; sourceTree = ""; }; 44 | 1B61EF9920E38B1C0051A489 /* DocumentPicker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DocumentPicker.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 1B61EF9C20E38B1C0051A489 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 46 | 1B61EF9D20E38B1C0051A489 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 47 | 1B61EF9F20E38B1C0051A489 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 48 | 1B61EFA020E38B1C0051A489 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 49 | 1B61EFA320E38B1C0051A489 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 50 | 1B61EFA520E38B1C0051A489 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 51 | 1B61EFA820E38B1C0051A489 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 52 | 1B61EFAA20E38B1C0051A489 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | 1B61EFAB20E38B1C0051A489 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 54 | 1B61EFB120E38B1C0051A489 /* DocumentPickerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DocumentPickerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 1B61EFB520E38B1C0051A489 /* DocumentPickerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DocumentPickerTests.m; sourceTree = ""; }; 56 | 1B61EFB720E38B1C0051A489 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 1B61EFBC20E38B1C0051A489 /* DocumentPickerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DocumentPickerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 1B61EFC020E38B1C0051A489 /* DocumentPickerUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DocumentPickerUITests.m; sourceTree = ""; }; 59 | 1B61EFC220E38B1C0051A489 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | 1B61EFCF20E38BD20051A489 /* NKSeleDocumentTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NKSeleDocumentTool.m; sourceTree = ""; }; 61 | 1B61EFD020E38BD20051A489 /* NKSeleDocumentTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NKSeleDocumentTool.h; sourceTree = ""; }; 62 | 1B61EFD320E390E80051A489 /* OtherFilesViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OtherFilesViewCell.h; sourceTree = ""; }; 63 | 1B61EFD420E390E80051A489 /* OtherFilesViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OtherFilesViewCell.m; sourceTree = ""; }; 64 | 1B61EFD620E393510051A489 /* NKOtherFilesModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NKOtherFilesModel.h; sourceTree = ""; }; 65 | 1B61EFD720E393510051A489 /* NKOtherFilesModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NKOtherFilesModel.m; sourceTree = ""; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFrameworksBuildPhase section */ 69 | 1B61EF9620E38B1C0051A489 /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | 1B61EFAE20E38B1C0051A489 /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | 1B61EFB920E38B1C0051A489 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | /* End PBXFrameworksBuildPhase section */ 91 | 92 | /* Begin PBXGroup section */ 93 | 1B61EF9020E38B1C0051A489 = { 94 | isa = PBXGroup; 95 | children = ( 96 | 1B61EF9B20E38B1C0051A489 /* DocumentPicker */, 97 | 1B61EFB420E38B1C0051A489 /* DocumentPickerTests */, 98 | 1B61EFBF20E38B1C0051A489 /* DocumentPickerUITests */, 99 | 1B61EF9A20E38B1C0051A489 /* Products */, 100 | ); 101 | sourceTree = ""; 102 | }; 103 | 1B61EF9A20E38B1C0051A489 /* Products */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 1B61EF9920E38B1C0051A489 /* DocumentPicker.app */, 107 | 1B61EFB120E38B1C0051A489 /* DocumentPickerTests.xctest */, 108 | 1B61EFBC20E38B1C0051A489 /* DocumentPickerUITests.xctest */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 1B61EF9B20E38B1C0051A489 /* DocumentPicker */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 1B61EFCE20E38BC30051A489 /* DocumentTool */, 117 | 1B61EF9C20E38B1C0051A489 /* AppDelegate.h */, 118 | 1B61EF9D20E38B1C0051A489 /* AppDelegate.m */, 119 | 1B61EF9F20E38B1C0051A489 /* ViewController.h */, 120 | 1B61EFA020E38B1C0051A489 /* ViewController.m */, 121 | 1B61EFD220E38FCE0051A489 /* View */, 122 | 1B61EFA220E38B1C0051A489 /* Main.storyboard */, 123 | 1B61EFA520E38B1C0051A489 /* Assets.xcassets */, 124 | 1B61EFA720E38B1C0051A489 /* LaunchScreen.storyboard */, 125 | 1B61EFAA20E38B1C0051A489 /* Info.plist */, 126 | 1B61EFAB20E38B1C0051A489 /* main.m */, 127 | ); 128 | path = DocumentPicker; 129 | sourceTree = ""; 130 | }; 131 | 1B61EFB420E38B1C0051A489 /* DocumentPickerTests */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 1B61EFB520E38B1C0051A489 /* DocumentPickerTests.m */, 135 | 1B61EFB720E38B1C0051A489 /* Info.plist */, 136 | ); 137 | path = DocumentPickerTests; 138 | sourceTree = ""; 139 | }; 140 | 1B61EFBF20E38B1C0051A489 /* DocumentPickerUITests */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 1B61EFC020E38B1C0051A489 /* DocumentPickerUITests.m */, 144 | 1B61EFC220E38B1C0051A489 /* Info.plist */, 145 | ); 146 | path = DocumentPickerUITests; 147 | sourceTree = ""; 148 | }; 149 | 1B61EFCE20E38BC30051A489 /* DocumentTool */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 1B61EFD020E38BD20051A489 /* NKSeleDocumentTool.h */, 153 | 1B61EFCF20E38BD20051A489 /* NKSeleDocumentTool.m */, 154 | ); 155 | path = DocumentTool; 156 | sourceTree = ""; 157 | }; 158 | 1B61EFD220E38FCE0051A489 /* View */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 1B24139A20E3C2B100FBD773 /* UIActionSheet+Blocks.h */, 162 | 1B24139920E3C2B100FBD773 /* UIActionSheet+Blocks.m */, 163 | 1B61EFD320E390E80051A489 /* OtherFilesViewCell.h */, 164 | 1B61EFD420E390E80051A489 /* OtherFilesViewCell.m */, 165 | 1B61EFD620E393510051A489 /* NKOtherFilesModel.h */, 166 | 1B61EFD720E393510051A489 /* NKOtherFilesModel.m */, 167 | ); 168 | path = View; 169 | sourceTree = ""; 170 | }; 171 | /* End PBXGroup section */ 172 | 173 | /* Begin PBXNativeTarget section */ 174 | 1B61EF9820E38B1C0051A489 /* DocumentPicker */ = { 175 | isa = PBXNativeTarget; 176 | buildConfigurationList = 1B61EFC520E38B1C0051A489 /* Build configuration list for PBXNativeTarget "DocumentPicker" */; 177 | buildPhases = ( 178 | 1B61EF9520E38B1C0051A489 /* Sources */, 179 | 1B61EF9620E38B1C0051A489 /* Frameworks */, 180 | 1B61EF9720E38B1C0051A489 /* Resources */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | ); 186 | name = DocumentPicker; 187 | productName = DocumentPicker; 188 | productReference = 1B61EF9920E38B1C0051A489 /* DocumentPicker.app */; 189 | productType = "com.apple.product-type.application"; 190 | }; 191 | 1B61EFB020E38B1C0051A489 /* DocumentPickerTests */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = 1B61EFC820E38B1C0051A489 /* Build configuration list for PBXNativeTarget "DocumentPickerTests" */; 194 | buildPhases = ( 195 | 1B61EFAD20E38B1C0051A489 /* Sources */, 196 | 1B61EFAE20E38B1C0051A489 /* Frameworks */, 197 | 1B61EFAF20E38B1C0051A489 /* Resources */, 198 | ); 199 | buildRules = ( 200 | ); 201 | dependencies = ( 202 | 1B61EFB320E38B1C0051A489 /* PBXTargetDependency */, 203 | ); 204 | name = DocumentPickerTests; 205 | productName = DocumentPickerTests; 206 | productReference = 1B61EFB120E38B1C0051A489 /* DocumentPickerTests.xctest */; 207 | productType = "com.apple.product-type.bundle.unit-test"; 208 | }; 209 | 1B61EFBB20E38B1C0051A489 /* DocumentPickerUITests */ = { 210 | isa = PBXNativeTarget; 211 | buildConfigurationList = 1B61EFCB20E38B1C0051A489 /* Build configuration list for PBXNativeTarget "DocumentPickerUITests" */; 212 | buildPhases = ( 213 | 1B61EFB820E38B1C0051A489 /* Sources */, 214 | 1B61EFB920E38B1C0051A489 /* Frameworks */, 215 | 1B61EFBA20E38B1C0051A489 /* Resources */, 216 | ); 217 | buildRules = ( 218 | ); 219 | dependencies = ( 220 | 1B61EFBE20E38B1C0051A489 /* PBXTargetDependency */, 221 | ); 222 | name = DocumentPickerUITests; 223 | productName = DocumentPickerUITests; 224 | productReference = 1B61EFBC20E38B1C0051A489 /* DocumentPickerUITests.xctest */; 225 | productType = "com.apple.product-type.bundle.ui-testing"; 226 | }; 227 | /* End PBXNativeTarget section */ 228 | 229 | /* Begin PBXProject section */ 230 | 1B61EF9120E38B1C0051A489 /* Project object */ = { 231 | isa = PBXProject; 232 | attributes = { 233 | LastUpgradeCheck = 0910; 234 | ORGANIZATIONNAME = "聂宽"; 235 | TargetAttributes = { 236 | 1B61EF9820E38B1C0051A489 = { 237 | CreatedOnToolsVersion = 9.1; 238 | ProvisioningStyle = Manual; 239 | }; 240 | 1B61EFB020E38B1C0051A489 = { 241 | CreatedOnToolsVersion = 9.1; 242 | ProvisioningStyle = Automatic; 243 | TestTargetID = 1B61EF9820E38B1C0051A489; 244 | }; 245 | 1B61EFBB20E38B1C0051A489 = { 246 | CreatedOnToolsVersion = 9.1; 247 | ProvisioningStyle = Automatic; 248 | TestTargetID = 1B61EF9820E38B1C0051A489; 249 | }; 250 | }; 251 | }; 252 | buildConfigurationList = 1B61EF9420E38B1C0051A489 /* Build configuration list for PBXProject "DocumentPicker" */; 253 | compatibilityVersion = "Xcode 8.0"; 254 | developmentRegion = en; 255 | hasScannedForEncodings = 0; 256 | knownRegions = ( 257 | en, 258 | Base, 259 | ); 260 | mainGroup = 1B61EF9020E38B1C0051A489; 261 | productRefGroup = 1B61EF9A20E38B1C0051A489 /* Products */; 262 | projectDirPath = ""; 263 | projectRoot = ""; 264 | targets = ( 265 | 1B61EF9820E38B1C0051A489 /* DocumentPicker */, 266 | 1B61EFB020E38B1C0051A489 /* DocumentPickerTests */, 267 | 1B61EFBB20E38B1C0051A489 /* DocumentPickerUITests */, 268 | ); 269 | }; 270 | /* End PBXProject section */ 271 | 272 | /* Begin PBXResourcesBuildPhase section */ 273 | 1B61EF9720E38B1C0051A489 /* Resources */ = { 274 | isa = PBXResourcesBuildPhase; 275 | buildActionMask = 2147483647; 276 | files = ( 277 | 1B61EFA920E38B1C0051A489 /* LaunchScreen.storyboard in Resources */, 278 | 1B61EFA620E38B1C0051A489 /* Assets.xcassets in Resources */, 279 | 1B61EFA420E38B1C0051A489 /* Main.storyboard in Resources */, 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | 1B61EFAF20E38B1C0051A489 /* Resources */ = { 284 | isa = PBXResourcesBuildPhase; 285 | buildActionMask = 2147483647; 286 | files = ( 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | 1B61EFBA20E38B1C0051A489 /* Resources */ = { 291 | isa = PBXResourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | ); 295 | runOnlyForDeploymentPostprocessing = 0; 296 | }; 297 | /* End PBXResourcesBuildPhase section */ 298 | 299 | /* Begin PBXSourcesBuildPhase section */ 300 | 1B61EF9520E38B1C0051A489 /* Sources */ = { 301 | isa = PBXSourcesBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | 1B61EFA120E38B1C0051A489 /* ViewController.m in Sources */, 305 | 1B24139B20E3C2B100FBD773 /* UIActionSheet+Blocks.m in Sources */, 306 | 1B61EFD520E390E80051A489 /* OtherFilesViewCell.m in Sources */, 307 | 1B61EFAC20E38B1C0051A489 /* main.m in Sources */, 308 | 1B61EFD120E38BD20051A489 /* NKSeleDocumentTool.m in Sources */, 309 | 1B61EF9E20E38B1C0051A489 /* AppDelegate.m in Sources */, 310 | 1B61EFD820E393510051A489 /* NKOtherFilesModel.m in Sources */, 311 | ); 312 | runOnlyForDeploymentPostprocessing = 0; 313 | }; 314 | 1B61EFAD20E38B1C0051A489 /* Sources */ = { 315 | isa = PBXSourcesBuildPhase; 316 | buildActionMask = 2147483647; 317 | files = ( 318 | 1B61EFB620E38B1C0051A489 /* DocumentPickerTests.m in Sources */, 319 | ); 320 | runOnlyForDeploymentPostprocessing = 0; 321 | }; 322 | 1B61EFB820E38B1C0051A489 /* Sources */ = { 323 | isa = PBXSourcesBuildPhase; 324 | buildActionMask = 2147483647; 325 | files = ( 326 | 1B61EFC120E38B1C0051A489 /* DocumentPickerUITests.m in Sources */, 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | /* End PBXSourcesBuildPhase section */ 331 | 332 | /* Begin PBXTargetDependency section */ 333 | 1B61EFB320E38B1C0051A489 /* PBXTargetDependency */ = { 334 | isa = PBXTargetDependency; 335 | target = 1B61EF9820E38B1C0051A489 /* DocumentPicker */; 336 | targetProxy = 1B61EFB220E38B1C0051A489 /* PBXContainerItemProxy */; 337 | }; 338 | 1B61EFBE20E38B1C0051A489 /* PBXTargetDependency */ = { 339 | isa = PBXTargetDependency; 340 | target = 1B61EF9820E38B1C0051A489 /* DocumentPicker */; 341 | targetProxy = 1B61EFBD20E38B1C0051A489 /* PBXContainerItemProxy */; 342 | }; 343 | /* End PBXTargetDependency section */ 344 | 345 | /* Begin PBXVariantGroup section */ 346 | 1B61EFA220E38B1C0051A489 /* Main.storyboard */ = { 347 | isa = PBXVariantGroup; 348 | children = ( 349 | 1B61EFA320E38B1C0051A489 /* Base */, 350 | ); 351 | name = Main.storyboard; 352 | sourceTree = ""; 353 | }; 354 | 1B61EFA720E38B1C0051A489 /* LaunchScreen.storyboard */ = { 355 | isa = PBXVariantGroup; 356 | children = ( 357 | 1B61EFA820E38B1C0051A489 /* Base */, 358 | ); 359 | name = LaunchScreen.storyboard; 360 | sourceTree = ""; 361 | }; 362 | /* End PBXVariantGroup section */ 363 | 364 | /* Begin XCBuildConfiguration section */ 365 | 1B61EFC320E38B1C0051A489 /* Debug */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | ALWAYS_SEARCH_USER_PATHS = NO; 369 | CLANG_ANALYZER_NONNULL = YES; 370 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 371 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 372 | CLANG_CXX_LIBRARY = "libc++"; 373 | CLANG_ENABLE_MODULES = YES; 374 | CLANG_ENABLE_OBJC_ARC = YES; 375 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 376 | CLANG_WARN_BOOL_CONVERSION = YES; 377 | CLANG_WARN_COMMA = YES; 378 | CLANG_WARN_CONSTANT_CONVERSION = YES; 379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 380 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 381 | CLANG_WARN_EMPTY_BODY = YES; 382 | CLANG_WARN_ENUM_CONVERSION = YES; 383 | CLANG_WARN_INFINITE_RECURSION = YES; 384 | CLANG_WARN_INT_CONVERSION = YES; 385 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 386 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 387 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 388 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 389 | CLANG_WARN_STRICT_PROTOTYPES = YES; 390 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 391 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 392 | CLANG_WARN_UNREACHABLE_CODE = YES; 393 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 394 | CODE_SIGN_IDENTITY = "iPhone Developer"; 395 | COPY_PHASE_STRIP = NO; 396 | DEBUG_INFORMATION_FORMAT = dwarf; 397 | ENABLE_STRICT_OBJC_MSGSEND = YES; 398 | ENABLE_TESTABILITY = YES; 399 | GCC_C_LANGUAGE_STANDARD = gnu11; 400 | GCC_DYNAMIC_NO_PIC = NO; 401 | GCC_NO_COMMON_BLOCKS = YES; 402 | GCC_OPTIMIZATION_LEVEL = 0; 403 | GCC_PREPROCESSOR_DEFINITIONS = ( 404 | "DEBUG=1", 405 | "$(inherited)", 406 | ); 407 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 408 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 409 | GCC_WARN_UNDECLARED_SELECTOR = YES; 410 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 411 | GCC_WARN_UNUSED_FUNCTION = YES; 412 | GCC_WARN_UNUSED_VARIABLE = YES; 413 | IPHONEOS_DEPLOYMENT_TARGET = 11.1; 414 | MTL_ENABLE_DEBUG_INFO = YES; 415 | ONLY_ACTIVE_ARCH = YES; 416 | SDKROOT = iphoneos; 417 | }; 418 | name = Debug; 419 | }; 420 | 1B61EFC420E38B1C0051A489 /* Release */ = { 421 | isa = XCBuildConfiguration; 422 | buildSettings = { 423 | ALWAYS_SEARCH_USER_PATHS = NO; 424 | CLANG_ANALYZER_NONNULL = YES; 425 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 426 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 427 | CLANG_CXX_LIBRARY = "libc++"; 428 | CLANG_ENABLE_MODULES = YES; 429 | CLANG_ENABLE_OBJC_ARC = YES; 430 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 431 | CLANG_WARN_BOOL_CONVERSION = YES; 432 | CLANG_WARN_COMMA = YES; 433 | CLANG_WARN_CONSTANT_CONVERSION = YES; 434 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 435 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 436 | CLANG_WARN_EMPTY_BODY = YES; 437 | CLANG_WARN_ENUM_CONVERSION = YES; 438 | CLANG_WARN_INFINITE_RECURSION = YES; 439 | CLANG_WARN_INT_CONVERSION = YES; 440 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 441 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 442 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 443 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 444 | CLANG_WARN_STRICT_PROTOTYPES = YES; 445 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 446 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 447 | CLANG_WARN_UNREACHABLE_CODE = YES; 448 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 449 | CODE_SIGN_IDENTITY = "iPhone Developer"; 450 | COPY_PHASE_STRIP = NO; 451 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 452 | ENABLE_NS_ASSERTIONS = NO; 453 | ENABLE_STRICT_OBJC_MSGSEND = YES; 454 | GCC_C_LANGUAGE_STANDARD = gnu11; 455 | GCC_NO_COMMON_BLOCKS = YES; 456 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 457 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 458 | GCC_WARN_UNDECLARED_SELECTOR = YES; 459 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 460 | GCC_WARN_UNUSED_FUNCTION = YES; 461 | GCC_WARN_UNUSED_VARIABLE = YES; 462 | IPHONEOS_DEPLOYMENT_TARGET = 11.1; 463 | MTL_ENABLE_DEBUG_INFO = NO; 464 | SDKROOT = iphoneos; 465 | VALIDATE_PRODUCT = YES; 466 | }; 467 | name = Release; 468 | }; 469 | 1B61EFC620E38B1C0051A489 /* Debug */ = { 470 | isa = XCBuildConfiguration; 471 | buildSettings = { 472 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 473 | CODE_SIGN_STYLE = Manual; 474 | DEVELOPMENT_TEAM = 7P9459R55V; 475 | INFOPLIST_FILE = DocumentPicker/Info.plist; 476 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 477 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 478 | PRODUCT_BUNDLE_IDENTIFIER = com.DocumentPicker; 479 | PRODUCT_NAME = "$(TARGET_NAME)"; 480 | PROVISIONING_PROFILE = "08c7e264-4c8b-4c07-ad4d-2c9a35eb2a44"; 481 | PROVISIONING_PROFILE_SPECIFIER = NK_Common_Profile; 482 | TARGETED_DEVICE_FAMILY = "1,2"; 483 | }; 484 | name = Debug; 485 | }; 486 | 1B61EFC720E38B1C0051A489 /* Release */ = { 487 | isa = XCBuildConfiguration; 488 | buildSettings = { 489 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 490 | CODE_SIGN_STYLE = Manual; 491 | DEVELOPMENT_TEAM = 7P9459R55V; 492 | INFOPLIST_FILE = DocumentPicker/Info.plist; 493 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 494 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 495 | PRODUCT_BUNDLE_IDENTIFIER = com.DocumentPicker; 496 | PRODUCT_NAME = "$(TARGET_NAME)"; 497 | PROVISIONING_PROFILE = "08c7e264-4c8b-4c07-ad4d-2c9a35eb2a44"; 498 | PROVISIONING_PROFILE_SPECIFIER = NK_Common_Profile; 499 | TARGETED_DEVICE_FAMILY = "1,2"; 500 | }; 501 | name = Release; 502 | }; 503 | 1B61EFC920E38B1C0051A489 /* Debug */ = { 504 | isa = XCBuildConfiguration; 505 | buildSettings = { 506 | BUNDLE_LOADER = "$(TEST_HOST)"; 507 | CODE_SIGN_STYLE = Automatic; 508 | DEVELOPMENT_TEAM = 584PEA54RY; 509 | INFOPLIST_FILE = DocumentPickerTests/Info.plist; 510 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 511 | PRODUCT_BUNDLE_IDENTIFIER = com.DocumentPickerTests; 512 | PRODUCT_NAME = "$(TARGET_NAME)"; 513 | TARGETED_DEVICE_FAMILY = "1,2"; 514 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DocumentPicker.app/DocumentPicker"; 515 | }; 516 | name = Debug; 517 | }; 518 | 1B61EFCA20E38B1C0051A489 /* Release */ = { 519 | isa = XCBuildConfiguration; 520 | buildSettings = { 521 | BUNDLE_LOADER = "$(TEST_HOST)"; 522 | CODE_SIGN_STYLE = Automatic; 523 | DEVELOPMENT_TEAM = 584PEA54RY; 524 | INFOPLIST_FILE = DocumentPickerTests/Info.plist; 525 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 526 | PRODUCT_BUNDLE_IDENTIFIER = com.DocumentPickerTests; 527 | PRODUCT_NAME = "$(TARGET_NAME)"; 528 | TARGETED_DEVICE_FAMILY = "1,2"; 529 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DocumentPicker.app/DocumentPicker"; 530 | }; 531 | name = Release; 532 | }; 533 | 1B61EFCC20E38B1C0051A489 /* Debug */ = { 534 | isa = XCBuildConfiguration; 535 | buildSettings = { 536 | CODE_SIGN_STYLE = Automatic; 537 | DEVELOPMENT_TEAM = 584PEA54RY; 538 | INFOPLIST_FILE = DocumentPickerUITests/Info.plist; 539 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 540 | PRODUCT_BUNDLE_IDENTIFIER = com.DocumentPickerUITests; 541 | PRODUCT_NAME = "$(TARGET_NAME)"; 542 | TARGETED_DEVICE_FAMILY = "1,2"; 543 | TEST_TARGET_NAME = DocumentPicker; 544 | }; 545 | name = Debug; 546 | }; 547 | 1B61EFCD20E38B1C0051A489 /* Release */ = { 548 | isa = XCBuildConfiguration; 549 | buildSettings = { 550 | CODE_SIGN_STYLE = Automatic; 551 | DEVELOPMENT_TEAM = 584PEA54RY; 552 | INFOPLIST_FILE = DocumentPickerUITests/Info.plist; 553 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 554 | PRODUCT_BUNDLE_IDENTIFIER = com.DocumentPickerUITests; 555 | PRODUCT_NAME = "$(TARGET_NAME)"; 556 | TARGETED_DEVICE_FAMILY = "1,2"; 557 | TEST_TARGET_NAME = DocumentPicker; 558 | }; 559 | name = Release; 560 | }; 561 | /* End XCBuildConfiguration section */ 562 | 563 | /* Begin XCConfigurationList section */ 564 | 1B61EF9420E38B1C0051A489 /* Build configuration list for PBXProject "DocumentPicker" */ = { 565 | isa = XCConfigurationList; 566 | buildConfigurations = ( 567 | 1B61EFC320E38B1C0051A489 /* Debug */, 568 | 1B61EFC420E38B1C0051A489 /* Release */, 569 | ); 570 | defaultConfigurationIsVisible = 0; 571 | defaultConfigurationName = Release; 572 | }; 573 | 1B61EFC520E38B1C0051A489 /* Build configuration list for PBXNativeTarget "DocumentPicker" */ = { 574 | isa = XCConfigurationList; 575 | buildConfigurations = ( 576 | 1B61EFC620E38B1C0051A489 /* Debug */, 577 | 1B61EFC720E38B1C0051A489 /* Release */, 578 | ); 579 | defaultConfigurationIsVisible = 0; 580 | defaultConfigurationName = Release; 581 | }; 582 | 1B61EFC820E38B1C0051A489 /* Build configuration list for PBXNativeTarget "DocumentPickerTests" */ = { 583 | isa = XCConfigurationList; 584 | buildConfigurations = ( 585 | 1B61EFC920E38B1C0051A489 /* Debug */, 586 | 1B61EFCA20E38B1C0051A489 /* Release */, 587 | ); 588 | defaultConfigurationIsVisible = 0; 589 | defaultConfigurationName = Release; 590 | }; 591 | 1B61EFCB20E38B1C0051A489 /* Build configuration list for PBXNativeTarget "DocumentPickerUITests" */ = { 592 | isa = XCConfigurationList; 593 | buildConfigurations = ( 594 | 1B61EFCC20E38B1C0051A489 /* Debug */, 595 | 1B61EFCD20E38B1C0051A489 /* Release */, 596 | ); 597 | defaultConfigurationIsVisible = 0; 598 | defaultConfigurationName = Release; 599 | }; 600 | /* End XCConfigurationList section */ 601 | }; 602 | rootObject = 1B61EF9120E38B1C0051A489 /* Project object */; 603 | } 604 | --------------------------------------------------------------------------------