前言网络
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要保持一致,不然在上传审核包的时候会提示警告,致使程序没法正常提审。