大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
AirDrop概览
成都创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:做网站、网站制作、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的复兴网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
AirDrop是iOS 7引入的一项新功能,iCloud同步功能允许在用户的两台iOS设备之间分享照片和文档,而AirDrop可以在不同用户的iOS设备之间进行照片和文档的分享。
在iOS 7之前,iOS用户主要依靠第三方app实现iOS设备间的文件和数据分享,在iOS 7中,该项新功能适用于所有iPhone 5、iPad 4、iPad mini以及第五代iPod touch设备。通过AirDrop,你可以与附近其他iOS app分享照片、视频、通讯录、URL、Passbook passes、App Store上的app列表、iTunes Store中的媒体列表以及地图中的位置信息等等。
苹果在iOS 7 SDK中集成了UIActivityViewController类,可以让你很简单地就能把AirDrop功能整合进app中。UIActivityViewController类封装了文件分享功能的细节。你所需要的就是告知这个类你希望分享的内容,以及处理的结果。在这个教程中,我们将会演示UIActivityViewController的使用方法,以及你该如何使用AirDrop来分享图片/文档。
AirDrop使用蓝牙来扫描周围的设备,当两台设备通过蓝牙建立起了连接,考虑到更快速的数据传输,它就会创建点对点的Wi-Fi网络来连接两部iOS 设备。但并不意味着为了使用AirDrop而需要把设备连接至Wi-Fi网络。
比如你想在iPhone拍照类app中将照片分享给另一位iPhone设备,假如你在两台设备间启动了AirDrop,点击屏幕左下角的分享按钮就能实现不同用户iOS 设备间的文件分享。当屏幕处于关闭状态时,AirDrop为不可用,所以要确保文件接收方的设备处于打开状态,然后选择设备进行分享。在另一台设备上,你会看到照片预览和确认要求。接收者可以接受或者拒绝接收文件。如果你选择了接收,照片会被传输至你的iOS设备,并保存至相册。
AirDrop并不仅仅适用于拍照类app,你也可以在大部分内置的应用中看到它,比如Contacts, iTunes, App Store, Safari以及其他应用程序中。
下面我们来看看如何把AirDrop整合进你的app。
UIActivityViewController简介快览
可能有开发者会觉得在应用中整合AirDrop比较麻烦,其实只需要数行代码就能实现,UIActivityViewController让这个过程变得非常简单,因为AirDrop是该类固定的一部分。
UIActivityViewController类是一个标准的view controller,提供了几项标准的服务,比如复制项目至剪贴板,把内容分享至社交网站,以及通过Messages发送数据等等。在iOS 7 SDK中,UIActivityViewController类提供了内置的AirDrop功能。
如果你有一些数据一批对象需要通过AirDrop进行分享,你所需要的是通过对象数组初始化UIActivityViewController,并展示在屏幕上:
UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:objectsToShare applicationActivities:nil];
[self presentViewController:controller animated:YES completion:nil];
如上代码所示,只需要两行代码,你就能通过AirDrop选项启用activity view。当检测到周围的设备时,activity controller会自动展示在设备上,并处理数据转换(如果你选择了该项)。
根据需要,你可以拒绝特定的分享类型,也就是说,你可以通过排除所有的活动仅展示通过AirDrop进行分享。如下代码所示:
UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:objectsToShare applicationActivities:nil];
NSArray *excludedActivities = @[UIActivityTypePostToTwitter, UIActivityTypePostToFacebook,
UIActivityTypePostToWeibo,
UIActivityTypeMessage, UIActivityTypeMail,
UIActivityTypePrint, UIActivityTypeCopyToPasteboard,
UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll,
UIActivityTypeAddToReadingList, UIActivityTypePostToFlickr,
UIActivityTypePostToVimeo, UIActivityTypePostToTencentWeibo];
controller.excludedActivityTypes = excludedActivities;
[self presentViewController:controller animated:YES completion:nil];
现在activity view controller仅展示AirDrop选项:
你可以通过UIActivityViewController来分享不同的数据类型,包括NSString, UIImage以及NSURL。你不仅可以使用NSURL分享链接,也可以通过URL传递任何类型的文件。
在接收端,当其他设备接收数据时,它会基于数据类型自动打来app。也就是说,如果传送的是UIImage时,被接收的图片会展示在拍照类app中。当传递的是PDF文件时,其他设备会在Safari中打开它。如果你仅仅分享NSString object,数据将会被展示在Notes app中。
AirDrop Demo App介绍
现在我们创建一个AirDrop demo app来帮你更好地理解UIActivityViewController和AirDrop。这个示例app非常简单,当首次启动,你会看到罗列了几个文件的表格视图,包括图片文件、PDF文件以及文本文件,你可以点击文件并查看内容。在content view中,会看到一个屏幕右上角有一个操作按钮。点击按钮将启用AirDrop选项,并且你可以与周围设备分享图片或者文档。
你可以从头开始做这个app,但是为了节省时间,你可以下载这个项目模板来试验。打开Xcode project,你会发现下边这个Storyboard:
这个示例app已经执行了ListTableViewController和DocumentViewController。如果编译并运行这个app,你会发现一个文件列表。点击任何一个文件,图片或者文档内容将会展示出来。但是分享按钮并没有被执行,这也是我们将要讨论的一点。
添加AirDrop功能
在工程模板中,ListTableViewController被用来在表格视图中展示文件列表,而DocumentViewController则通过web view来展示文档内容。document view中的操作按钮和DocumentViewController的share: method有关。该方法的实现如下所示:
- (IBAction)share:(id)sender {
NSURL *url = [self fileToURL:self.documentName];
NSArray *objectsToShare = @[url];
UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:objectsToShare applicationActivities:nil];
// Exclude all activities except AirDrop.
NSArray *excludedActivities = @[UIActivityTypePostToTwitter, UIActivityTypePostToFacebook,
UIActivityTypePostToWeibo,
UIActivityTypeMessage, UIActivityTypeMail,
UIActivityTypePrint, UIActivityTypeCopyToPasteboard,
UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll,
UIActivityTypeAddToReadingList, UIActivityTypePostToFlickr,
UIActivityTypePostToVimeo, UIActivityTypePostToTencentWeibo];
controller.excludedActivityTypes = excludedActivities;
// Present the controller
[self presentViewController:controller animated:YES completion:nil];
}
这个代码非常熟悉,我们在最开始的时候已经讨论过了,它可以用来简单地创建UIActivityViewController,排除所有分享功能(AirDrop除外),并作为模态视图展示出控制器。棘手的部分是如何定义分享的对象。下边我们将会把分享文件转换成NSURL object,并把文件URL作为数组传递给AirDrop。
头两行代码是关于file URL转换的。documentName属性存储了当前文件(比如ios-game-kit-sample.pdf),展示在document view中。我们通过文档名称和它返回的相应的file URL,来简单地调用fileToURL: method。fileToURL: method已经在工程模板中,代码如下:
- (NSURL *) fileToURL:(NSString*)filename
{
NSArray *fileComponents = [filename componentsSeparatedByString:@"."];
NSString *filePath = [[NSBundle mainBundle] pathForResource:[fileComponents objectAtIndex:0] ofType:[fileComponents objectAtIndex:1]];
return [NSURL fileURLWithPath:filePath];
}
这些代码非常简洁明了,比如ios-game-kit-sample.pdf将会被转换为
%20Support/iPhone%20Simulator/7.0.3/Applications/A5321493-318A-4A3B-8B37-E56B8B4405FC/AirDropDemo.app/ios-
game-kit-sample.pdf.
file URL依据你运行的设备而变化,但是URL应该以“file://”协议开头。通过file URL object,我们创建了相应的数组,并把它传递给UIActivityViewController以用来进行AirDrop分享。
编译并运行AirDrop demo
做完这些后,编译并在iPhone上运行这个app。
注意:你需要一个真实的设备来测试AirDrop分享。不能在模拟器上进行分享。
Uniform Type Identifiers (UTIs)统一标示符(UTIs)
当你把图片分享之其他iOS设备,接收方会自动打开拍照类app并加载图片。如果你传递的是PDF文件,接收方设备可能会提示你选择一个app来打开文件,或者直接在iBooks中打开。iOS是如何知道哪个app适合什么样的数据类型呢?
在系统中,苹果用UTIs来处理数据类型的标示。简单的说,一个uti是用来标示特定类型的数据或文件。例如,com.adobe.pdf标示一个pdf文件,而public.png代表一个PNG图片。在这里可以查看已经在系统中注册了的完整的UTIs清单。(love cc cat)应用程序可以打开在iOS系统中已经注册了的UTI。因此无论文件是否被打开,iOS都会用特定的程序打开这个文件。
系统允许多个程序注册相同的UTI。在这个教程中,iOS将通过app列表打开文件。比如,当你分享PDF文档时,你可以在接收端设备上看到如下屏幕:
总结
AirDrop是iOS 7引入的一个非常酷的功能,它为iOS设备间数据分享提供了一个很好的方法。首先,内置的UIActivityViewController类使得开发者在应用中实现该功能变得非常简单。正如你所看到的demo app,它仅仅需要几行代码就能实现。所以推荐开发者在应用中实现该功能。
1 UIFileSharingEnabled 设置为YES
并设置如下的格式告诉系统你能处理这个类型的文件
2 设置info.plist里添加可以读取PDF功能 如图所示
3 当第三方应用选择你的程序后,回自动触发– application:openURL:sourceApplication:annotation:. 你要做的就是在该方法里实现打开这个PDF即可:
4 但如果你要打开自定义的文件格式则需要告诉系统你的自定义格式 UIExportedTypeDeclarations 并新增一个item 可能你会问为什么PDF不用设置这个,因为系统已经默认支持PDF所以不用在设置一个PDF对应的UIExportedTypeDeclaration。 如图所示
5 分享文件的属性设置可以在这里查看
6 文件的复制、删除,请看下面的这篇文章
在最近参与的项目过程中,我发现一个有趣的现象。国内的App开发者,在设计“分享”这个功能的时候,一般都会根据业务的实际需要,设计一套自定义的解决方案,我们姑且称之为“自定义分享插件”。而相比之下,国外的开发者更倾向于使用iOS提供的系统级的Share Extension,我们姑且称之为“原生分享插件”。那么,这两种方案,各有什么特色和优缺点呢?
什么是原生分享插件?
我们先来简单看一下什么是苹果的原生分享插件Share Extension。前面说过,由于中国App开发大量使用自定义的分享方式,所以可能很多设计师还不熟悉原生分享的机制。另外,苹果直到去年的iOS8.0才重新定义了iOS的Extension机制,并重新设计了Share Extension,使得她真正变得好用而受到开发者的认可。所以,原生分享插件对于我们来说,其实还挺新的:)
在早先版本里,从iOS5到iOS6,乃至iOS7,分享插件的界面设计进过了几次变更,但是功能上一直十分有限,一开始仅限于系统级和系统原生应用的内容传递,例如发送照片内容到邮件和短信,或者从Safari保存网页等。后来苹果通过与Twitter和Facebook等几家公司签订独立的协议,实现了整合的方案,使内容分享到这些应用的过程更方便。
但是苹果显然也意识到了这一点,即系统和应用,以及应用与应用之间传递内容信息的需求是用户真实存在的需求,需要一个真正系统级的解决方案,就像当年的Push Notification那样,一个方案解决所有App的问题,而不是一家一家地去签协议。
所以,在去年的iOS8发布时,苹果对分享机制做了大刀阔斧的改变,这就是新的Share Extension,原生分享插件。App开发者只需要在开发过程中,为App加入原生分享插件,向系统注册,就可以通过Extension来实现与系统和其他App的内容分享了。原生分享插件就相当于一个中间媒介,可以接受Host App(发送内容的App)提交的内容,转交给想要分享到的Containing App(接受内容的App)。、
举例来说,如果你开发的是一个电商类App,希望鼓励用户把App上的商品分享给他们的朋友或者社交媒体,那么通过挂载和注册原生分享插件,以后用户想要分享App上的内容时,唤出分享界面,就可以把内容分享到系统上的任一(注册了分享插件的)位置。相反,如果你开发的是一个社交App,并鼓励用户从其他内容源分享内容你的App,同样需要注册到分享插件,表明你同意接受由它发送来的内容。
当然,不同形式的内容也不是随便就到处传递的。无论你是发送内容的Host App,还是接受内容的Containing App,都需要向原生分享插件描述清楚,要发送或接受的内容是什么格式,比如图片视频、文本还是链接。这被称为Activation Rules。也就是说,假如用户要分享的是一段文字,那么当他点击分享按钮时,弹出的Share Sheet上,就不会显示Instagram和Pintrest这类App,因为他们只接受图片分享。这也就是说,尽管是同一个原生分享组件,但是在不同的App上,它出现时显示的内容会自动根据要分享出去的内容性质做出变化。
所以,iOS的Share Extension原生分享插件,就像一个巨大的内容中转站,在系统和App,以及App之间建立起关联,方便内容的传递。
那么为什么要采用这样一种集成式的设计思路,而不是鼓励各App之间点对点传输呢?
最大的优势就是安全性和便利性。
iOS上的App被设计在一个“沙盒”里,App与系统间,以及App与另一个App之间的数据传输是受到严格限制的。所以我们经常遇到App在使用相机、相册或者GPS传感器时,都要请求用户同意的场景。这样设计的好处就是苹果的设备安全系数很高,恶意软件和病毒很难入侵。在这种情况下,如果系统允许App随便传递内容信息,肯定是不行的。App们互相之间如果要传递信息,也要先建立信任,也就是授权。所以在没有原生分享插件的时候,每一次分享动作,伴随的都是可能要一次新的授权(如果你自定义分享插件,情况便是如此)。而原生分享插件,就是将这些授权全都集中起来,由系统平台一次完成(App向系统注册时)。这样,iOS通过这种集成的方式,既能保证沙盒机制不被破坏,又实现了系统层面的信息分享。
当App注册了原生分享插件,一方面,它就可以通过插件向系统和其他所有(也注册了分享插件)的App发送内容,只要对方接受内容的形式(图片、文本等)。另一方面,它也同意接受来自插件的相应内容。这意味着,用户在iOS设备上,从任意一个App分享内容到其他任意一个App时,都不用再额外进行一个App之间的授权动作了。分享真正变成系统级别的,无处不在的。
并且,这个方案的系统整合程度很高,意味着,在实际的交互场景中,用户甚至可以不用跳转到他要分享的那个App里去操作,而是直接在当前界面完成分享,然后继续该干嘛干嘛。
讲完了这些,那么问题来了:
既然苹果的这套Share Extension机制这么好,为什么国内的App们还偏要自定义分享插件呢?
最大的问题在于,App的开发者想要分享内容到甲乙丙,而原生分享插件显示的是ABC。
苹果在设计原生分享插件时,是从所有用户的习惯角度出发的,如果用户经常分享内容到Facebook和Pintrest,而不常用Twitter,那么他可以通过Share的Action Sheet上的“更多”按钮,进入一个设置页面,在那里调整分享到App的顺序,甚至把不常用的分享渠道关掉。
这显然不符合国内一些开发者的口味,尤其是BAT这样的大公司。微信就关闭了对原生分享的支持,而选择了大量的自定义,所以我们可以看到微信的Share Sheet上出现了“收藏”、“调整字体”等跟分享毫无关系的功能。淘宝的分享也是自定义的。这类大公司的逻辑更多是让分享内容在自家的生态体系里流动,而不是整个平台。
一个非常有意思的特例是Pintrest。这家公司在自己的App上也使用了自定义的分享插件,为了方便用户把内容分享给App内的好友关系圈。但是如果在自定义的sheet上点击表示“更多”的那个“…”红色按钮,这是App又会调出原生分享插件。真是既满足了自己的小算盘,又照顾到了全平台的用户。而这样做的副作用就是,如果用户在第一个自定义Sheet上点击分享到Facebook,则调用系统分享编辑界面,而如果用户是在第二个原生分享sheet上点击,则会跳转到Facebook App里去做分享内容编辑。
调用下面的方法即可实现系统分享功能
//分享
- (IBAction)RespostClick_Action:(id)sender {
UIImage* image = [UIImage imageNamed:@"icon_share.png"];
NSString *text = @"I found an Awesome application software! InstaDown";
//;ls=1mt=8
NSURL *urlToShare = [NSURL URLWithString:[NSString stringWithFormat:@";ls=1mt=8",[HHLADSManager getValueFromjsondata:@"appid"]]];
NSArray *activityItems = @[text,image,urlToShare];
UIActivityViewController *avc = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:nil];
[self presentViewController:avc animated:TRUE completion:nil];
// 选中分享类型
[avc setCompletionWithItemsHandler:^(NSString * __nullable activityType, BOOL completed, NSArray * __nullable returnedItems, NSError * __nullable activityError){
// 显示选中的分享类型
NSLog(@"act type %@",activityType);
if (completed) {
NSLog(@"ok");
}else {
NSLog(@"no ok");
}
}];
UIPopoverPresentationController *popover = avc.popoverPresentationController;
if (popover) {
popover.sourceView = self.view;
popover.sourceRect = self.view.bounds;
popover.permittedArrowDirections = UIPopoverArrowDirectionUp;
}
}
这里主要讲利用分享扩展(share extension)实现系统分享到自己app的功能,扩展里面跳转宿主app,及数据传输等
创建成功会生成一个文件夹
info.plist 里面有激活扩展的规则,匹配规则会在系统分享里面出现自己的app。
NSExtensionActivationRule:默认为字符串“TRUEPREDICATE”,表示在分享菜单中一直显示该扩展。生产环境不可用,必须将类型改为Dictionary类型,然后添加以下字段:
默认分享扩展类ShareViewController,自带视图,可以全部自定义,这里不讲诉
跳转宿主app后在一下方法中处理逻辑
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionaryUIApplicationOpenURLOptionsKey,id *)options;
首先要配置相同的 App Groups,必须group.开头
NSUserDefaults *de = [[NSUserDefaults alloc]initWithSuiteName:@"group.(跟上面app groups一致)"];
[de setObject:value forKey:@"key"];
宿主app 获取数据
NSUserDefaults *de = [[NSUserDefaults alloc]initWithSuiteName:@"group.(跟上面app groups一致)"];
id value = [de objectForKey:@"key"];
扩展要选择对应宿主app运行,但扩展属于独立进程,调试的时候运行扩展,宿主app里面的断点不会走,同样运行宿主app,扩展里面的断点不会执行
1.在 ShareSDK()的官方上下载 SDK 并导入工程 将 ShareSDK 文件夹到项目文件夹中夹并拖入项目中。
2. 添加依赖框架(Framework) 打开项目设置中的 Build Phases 页,在“Link Binary With Libraries”一栏中,点击左下角的“+” 号;在弹出窗口里面分别以下库加入到项目中: SystemConfiguration.framework QuartzCore.framework MessageUI.framework libicucore.dylib
3.引入社区应用配置信息。 打开 main.m 文件加入
#import
如图:
(P.S. 此头文件必须在此文件下导入,否则会导致编译不通过) 4. 配置所有社交平台的 AppKey 打开 ShareSDKConfig.h 文件,根据需求设置各个平台的 App 相关信息(每个平台的 App 都需要到相 应平台上进行应用登记后来取的相关信息) 。如图:
5.
配置 URL Scheme 打开*-Info.plist(*代表你的工程名字) 。在配置文件中新增一项 URL types (如果存在可以不创建) 展开 URL types – URL Schemes, URL Schemes 下新增一项用于新浪微博 , 在 授权的 Scheme(如果不添加则会导致新浪微博的 SSO 授权方式无法返回应用) 。其填写格式为: sinaweibosso.2279784657,其中后面的数字段为你在新浪微博申请的 AppKey。如下图所示:
另外,如果需要使用微信或者 QQ 平台接口也需要在此项下面添加相应的 Scheme。 6.嵌入代码
打开*AppDelegate.m(*代表你的工程名字)�6�5 在
�6�5-
(BOOL)application:(UIApplication
*)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions �6�5 方法内添加如
下语句:
[ShareSDK registerApp:@"520520test"]; 然后,在处理请求 URL 的委托方法中加入 ShareSDK 的处理方法,如下: - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { return [ShareSDK handleOpenURL:url wxDelegate:self]; } - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [ShareSDK handleOpenURL:url wxDelegate:self]; } 此处理方法已包括微信和 QQ 的回复处理,如果使用 ShareSDK 内置提示功能可以不需要再实现消息的 微信和 QQ 的回复消息捕获。
7.分享内容 在分享内容部分 ShareSDK 提供了三种接口来满足不同需求的分享功能实现。 7.1 菜单方式分享: 使用此方式进行分享会首先弹出菜单供用户选择分享的目标平台, 然后再显示内容编辑界面供用户进 行分享内容编辑,最后进行分享。调用该方式的接口如下:
id publishContent = [ShareSDK publishContent:@"content" defaultContent:@"" image:[UIImage imageNamed:@"Icon.png"] imageQuality:0.8 mediaType:SSPublishContentMediaTypeNews title:@"ShareSDK" url:url musicFileUrl:nil extInfo:nil fileData:nil];
[ShareSDK showShareActionSheet:self share