ios10推送详解

qvii9023 8年前
   <p>上个月接到一个需求,做ios10的推送,意图冲击AppStore头条.瞬间抓狂,工具都还没有,于是赶紧安装xcodeBeta版,ios10Beta版,然后就开始无尽的查资料,毕竟新功能,毕竟没做过........不过还好,在发布会之前赶出来了,由于本人比较懒,拖到现在才写出来,接下来就是见证奇迹的时刻!</p>    <h2><strong>原理</strong></h2>    <p style="text-align:center"><img src="https://simg.open-open.com/show/793d2b3e5b390d990742292cbb5acad3.jpg"></p>    <p style="text-align:center">ios10 push1.jpg</p>    <p>图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider。</p>    <p>APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器。</p>    <p>上图可以分为三个阶段。</p>    <p>第一阶段:.net应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。</p>    <p>第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。</p>    <p>第三阶段:iPhone把发来的消息传递给相应的应用程序, 并且按照设定弹出Push通知。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/7447d7f1f5dd60f2d006ee7a0783ffb2.jpg"></p>    <p style="text-align:center">ios10 push2.jpg</p>    <p>从上图我们可以看到。</p>    <p>1、首先是应用程序注册消息推送。</p>    <p>2、 IOS跟APNS Server要deviceToken。应用程序接受deviceToken。</p>    <p>3、应用程序将deviceToken发送给PUSH服务端程序。</p>    <p>4、 服务端程序向APNS服务发送消息。</p>    <p>5、APNS服务将消息发送给iPhone应用程序。</p>    <p>xcode8以后测试环境证书就可以自动生成了,所以就不再多说.</p>    <h2><strong>创建</strong></h2>    <p>很久以前写过ios9的today extension,与其类似,同样需要创建一个target,</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b0f658b3bc317df10cb4e76e282fc7f6.png"></p>    <p style="text-align:center">D0B7D515-925E-4890-98EC-2150AC9C22E9.png</p>    <p>如图,Notification Content负责自定义通知UI,Notification Service Extension负责接收并处理数据</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/e9260d4fff761ddac54a0d3d171c3711.png"></p>    <p style="text-align:center">屏幕快照 2016-09-12 上午10.49.01.png</p>    <h2><strong>正活</strong></h2>    <p>ios的拓展类是不能独立联网请求数据的,但是之前做today的时候查过一些别的app,下拉通知栏的时候有些app可以抓到包,估计是单独做了一个网络请求的封装,只是瞎猜,如有雷同,纯属巧合.但是通知就不用那么麻烦了.首先从网上随便挑选一张图片(限定https协议): <a href="https://simg.open-open.com/show/d4b9ae6c1c970e3d2ea207647d62aa6e.jpg" rel="nofollow,noindex">https://homeba.s3.amazonaws.com/__sized__/scene/2c0f3bdb7715fed7190fd87e5e5340e4-1473387950-crop-c0-5__0-5-590x442-85.jpg</a> ,推送格式和可以自选,详情可见: <a href="/misc/goto?guid=4959715388019455038" rel="nofollow,noindex">https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html</a> .</p>    <p><img src="https://simg.open-open.com/show/bdc06641cefe2a674c71c6f2c8aedc28.png"></p>    <p>屏幕快照 2016-09-12 上午11.01.37.png</p>    <p>上图是我用的格式,"aps"内部的内容ios会自动获取归类.</p>    <p>alert是通知的文字内容,</p>    <p>sound是通知声音,在这取默认,</p>    <p>badge是否显示程序徽章,</p>    <p>重点是mutable-content,这个字段决定了调用自定义通知界面,也就是Notification Content控制器</p>    <p>category是和后台商量好的一个值,显示action,也就是通知下面的按钮,可以扩展一些操作而不必进入程序.</p>    <p>"aps"外部就可以添加一些需要的字段,这就看具体需求了.</p>    <p>推送工具方面的准备工作就已经完成了,下面开始代码干货.</p>    <pre>  <code class="language-objectivec">- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {  self.contentHandler = contentHandler;  self.bestAttemptContent = [request.content mutableCopy];    NSString * attchUrl = [request.content.userInfo objectForKey:@"image"];  //下载图片,放到本地  UIImage * imageFromUrl = [self getImageFromURL:attchUrl];    //获取documents目录  NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  NSString * documentsDirectoryPath = [paths objectAtIndex:0];    NSString * localPath = [self saveImage:imageFromUrl withFileName:@"MyImage" ofType:@"png" inDirectory:documentsDirectoryPath];  if (localPath && ![localPath isEqualToString:@""]) {      UNNotificationAttachment * attachment = [UNNotificationAttachment attachmentWithIdentifier:@"photo" URL:[NSURL URLWithString:[@"file://" stringByAppendingString:localPath]] options:nil error:nil];      if (attachment) {          self.bestAttemptContent.attachments = @[attachment];      }  }  self.contentHandler(self.bestAttemptContent);</code></pre>    <p>}</p>    <p>因为不能方便的使用SDImage框架,所以网络请求只能自己松手,丰衣足食,另外,ios10通知虽然可以加载图片,但是只能加载本地的图片,所以这里需要做一个处理,先把图片请求下来,再存到本地</p>    <pre>  <code class="language-objectivec">- (UIImage *) getImageFromURL:(NSString *)fileURL {  NSLog(@"执行图片下载函数");  UIImage * result;  //dataWithContentsOfURL方法需要https连接  NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];  result = [UIImage imageWithData:data];    return result;</code></pre>    <p>}</p>    <pre>  <code class="language-objectivec">//将所下载的图片保存到本地  -(NSString *) saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {  NSString *urlStr = @"";  if ([[extension lowercaseString] isEqualToString:@"png"])  {      urlStr = [directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]];      [UIImagePNGRepresentation(image) writeToFile:urlStr options:NSAtomicWrite error:nil];  } else if ([[extension lowercaseString] isEqualToString:@"jpg"] ||             [[extension lowercaseString] isEqualToString:@"jpeg"])  {      urlStr = [directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]];      [UIImageJPEGRepresentation(image, 1.0) writeToFile:urlStr options:NSAtomicWrite error:nil];  } else  {      NSLog(@"extension error");  }  return urlStr;</code></pre>    <p>}</p>    <p>然后数据方便就已经完成了,最后一步,自定义UI并获取图片.自带的storyboard还是很好用的.</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/0fb546e201170a023653e038e9a5220b.png"></p>    <p style="text-align:center">屏幕快照 2016-09-12 上午11.18.31.png</p>    <p>做好约束就可以加图片啦!</p>    <pre>  <code class="language-objectivec">- (void)didReceiveNotification:(UNNotification *)notification {  NSLog(@"嘿嘿");  self.label.text = notification.request.content.body;  UNNotificationContent * content = notification.request.content;  UNNotificationAttachment * attachment = content.attachments.firstObject;  if (attachment.URL.startAccessingSecurityScopedResource) {      self.imageView.image = [UIImage imageWithContentsOfFile:attachment.URL.path];  }</code></pre>    <p>}</p>    <p>就是这么简单,大功告成!!!(松一大口气.....)</p>    <p>来一个效果图,哈哈</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ba5a3883e34705dc93203fcca647fc52.png"><img src="https://simg.open-open.com/show/742f218609ea15c876a55324bffe4f6e.png"></p>    <p style="text-align:center">IMG_1456.PNG</p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/0b61698ecb5f</p>    <p> </p>