前言網絡
IOS擴展主要的目的是用戶能夠在 app 中使用其餘應用提供的功能,而無需離開當前的應用,所以能夠發如今瀏覽圖片或者是打開safari,點擊分享的按鈕,能夠分享至不少其餘的應用,這都是歸功於IOS share extension擴展強大之處,據個人瞭解目前大部分的應用都沒有實現擴展功能,因此網絡上能查詢到的資料不多,我也是嘗試着去了解其如何使用,我今天要講的並非如何去爲應用建立一個擴展,由於網絡上是有這方面的內容的,我側重講的自定義分享界面,由於可能系統自帶的UI界面並不能知足咱們應用的要求,自定義界面是勢在必行的;app
1、如何爲當前的應用添加share extension擴展,這個網絡上都有操做步驟,我就再也不重複。async
2、在建立好share extension中,去修改info.plist文件,如ide
如此設置表明着,擴展的入口爲CustomShareViewController(默認的是ShareViewController),接下來就是自定義佈局,你能夠在控制器中定義本身的UI交互,好比我作的簡單的佈局;佈局
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.6]; //定義一個容器視圖來存放分享內容和兩個操做按鈕 container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 175)]; container.center = self.view.center; container.layer.cornerRadius = 7; container.layer.borderColor = [UIColor lightGrayColor].CGColor; container.layer.borderWidth = 1; container.layer.masksToBounds = YES; container.backgroundColor = [UIColor whiteColor]; container.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; [self.view addSubview:container]; oldRect = container.frame; othorView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 220)]; othorView.center = self.view.center; othorView.layer.cornerRadius = 7; othorView.layer.borderColor = [UIColor lightGrayColor].CGColor; othorView.layer.borderWidth = 1; othorView.alpha = 0; othorView.layer.masksToBounds = YES; othorView.backgroundColor = [UIColor whiteColor]; othorView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; [self.view addSubview:othorView]; UIButton *backBut = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 65, 44)]; [backBut setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [backBut setTitle:@"返回" forState:UIControlStateNormal]; [backBut addTarget:self action:@selector(goBack:) forControlEvents:UIControlEventTouchUpInside]; textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 50, 200, 50)]; textView.text = @"測試"; [othorView addSubview:backBut]; [othorView addSubview:textView]; testBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 300, 44)]; UINavigationItem *ite = [[UINavigationItem alloc] initWithTitle:@"測試"]; //定義Post和Cancel按鈕 UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeSystem]; [cancelBtn setTitle:@"取消" forState:UIControlStateNormal]; cancelBtn.frame = CGRectMake(-15, 0, 65, 40); [cancelBtn addTarget:self action:@selector(cancelBtnClickHandler:) forControlEvents:UIControlEventTouchUpInside]; [container addSubview:cancelBtn]; UIButton *postBtn = [UIButton buttonWithType:UIButtonTypeSystem]; [postBtn setTitle:@"發送" forState:UIControlStateNormal]; postBtn.frame = CGRectMake(15, 0, 65, 40); [postBtn addTarget:self action:@selector(postBtnClickHandler:) forControlEvents:UIControlEventTouchUpInside]; [container addSubview:postBtn]; ite.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:cancelBtn]; ite.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:postBtn]; [testBar setItems:@[ite]]; [container addSubview:testBar]; [container addSubview:self.tableView]; //定義一個分享連接標籤 UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(8, cancelBtn.frame.origin.y + cancelBtn.frame.size.height + 8, container.frame.size.width - 16, container.frame.size.height - 16 - cancelBtn.frame.origin.y - cancelBtn.frame.size.height)]; label.numberOfLines = 0; label.textAlignment = NSTextAlignmentCenter; [container addSubview:label]; //獲取分享連接 __block BOOL hasGetUrl = NO; [self.extensionContext.inputItems enumerateObjectsUsingBlock:^(NSExtensionItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [obj.attachments enumerateObjectsUsingBlock:^(NSItemProvider * _Nonnull itemProvider, NSUInteger idx, BOOL * _Nonnull stop) { if ([itemProvider hasItemConformingToTypeIdentifier:@"public.url"]) { [itemProvider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id<NSSecureCoding> _Nullable item, NSError * _Null_unspecified error) { if ([(NSObject *)item isKindOfClass:[NSURL class]]) { dispatch_async(dispatch_get_main_queue(), ^{ label.text = ((NSURL *)item).absoluteString; }); } }]; hasGetUrl = YES; *stop = YES; } *stop = hasGetUrl; }]; }]; for (NSString *notificationName in @[UIKeyboardWillShowNotification, UIKeyboardWillHideNotification]) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:notificationName object:nil]; } }
其實就是簡單的視圖切換,固然你也能夠定製更加豐富的界面交互,這是跟業務需求掛鉤的;post
其中還須要注意的兩個方法:cancelRequestWithError與completeRequestReturningItems,這個是操做必須的方法,一個是錯誤執行,另外一個是成功執行返回,且執行都會關閉擴展程序界面。測試
- (void)cancelBtnClickHandler:(id)sender { [self.extensionContext cancelRequestWithError:[NSError errorWithDomain:@"CustomShareError" code:NSUserCancelledError userInfo:nil]]; } - (void)postBtnClickHandler:(id)sender { //執行分享內容處理 coverView = [[CoverView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:coverView]; [self performSelector:@selector(testAnima) withObject:nil afterDelay:0.1]; //[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil]; }
3、擴展中使用AFNetworking,網絡請求確定是必須的,具體的使用與在app中使用的同樣,如ui
AFHTTPSessionManager *httpClient = [AFAppHFAPIClient sharedClient]; [httpClient GET:urlString parameters:model progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { if (success) { success(responseObject); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (failed) { failed(error); } }];
可是,特別須要注意的是,擴展中是沒有[UIApplication sharedApplication]對象的,因此在操做提示界面的時候,這個是須要注意的。url
4、提交AppStore注意事項:spa
(1)擴展中的處理不能太長時間阻塞主線程(建議放入線程中到處理),不然可能致使蘋果拒絕你的應用。
(2)擴展不能單獨提審,必需要跟容器程序一塊兒提交AppStore進行審覈。
(3)提審的擴展和容器程序的Build Version要保持一致,不然在上傳審覈包的時候會提示警告,致使程序沒法正常提審。