iOS10发布后,简书优先开发增加了iOS10的新通知。本文分享整个feature的开发过程遇到的问题。
1、工程配置
Xcode8发生了很大的变化,直接打开原来的工程编译运行,这个时候是获取不到Push token的,打印didFailToRegisterForRemoteNotificationsWithError
中的error可以看到
fail to register with error Error Domain=NSCocoaErrorDomain Code=3000 "no valid ‘aps-environment‘ entitlement string found for application" UserInfo={NSLocalizedDescription=no valid ‘aps-environment‘ entitlement string found for application}
Google了解到是Xcode8的变化,entitlements
由本地的entitlements文件配置,主Target的Capabilities下,Push Notification
处于关闭的状态,必须手动打开。
2、Code Sign
工程增加了Notification Content
和Notification Service
两个Extension,Signing
默认是自动模式.。
据网上介绍Xcode8签名管理方式比Xcode7更智能,那我就试一下吧。选完Team它就自动生成了授权文件。然而,Xcode8还帮我生成了一个新的证书,相当于增加了一个开发人员,也就是我现在的证书不在原来的授权文件中,后果就是原来手动配置的授权文件要重新生成。
Certificates
这时候如果想使用原始的手动配置,不仅要把Automatically manage signing
去掉,还要在Key Chains
里把新生成的证书删掉,然后在Web端生成授权文件。使用Automatically manage signing
最好把每个Target都使用相同的方式。
3、Swift版本
如果你在创建Target的时候开发语言选了Swift,默认是使用Swift3.0,Xcode8同时支持3.0和2.3,可能你还没来及掌握3.0的API变化,想继续使用2.3的API,只要在对应Target的Build Setting
中Use Legacy Swift Language Version
设为YES就可以继续使用2.3。
4、Architectures
工程配好之后,只有模板代码,先跑起来写个Hello World
再说。Command+R
之后,编译报错了
Check dependenciesNo architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).
VALID_ARCHS
中没有对应的active arch
这时需要在对应Target的Build Setting
中Valid Architectures
中增加arm64
Architectures
5、Notification Service
接下来,开始代码编写了,大部分是参考喵神的这篇文章活久见的重构 - iOS 10 UserNotifications 框架解析和Demo、还有WWDC 708 Advanced Notifications、PDF。
在service中,我们会把后端push过来的数据中的图片下载到本地文件夹,然后作为attachments。
之前我们的推送都只显示一句alert,不过推送的json数据alert字段可以是string,也可以是dictionary,如果是string,相当于dictionary中的body
,在iOS8.2之后dictionary可以增加title
、subtitle
等。为了让推送更丰富,我们想把原来的body
变成title
,增加文章摘要放到body
里,如果直接改aps
内的alert
,那么8.2以前的设备推送显示的是文章摘要了。后来我们想了一个办法,Notification Service
不是可以修改推送内容吗?aps
的alert
还是保持不变,json增加一个新的title
和body
,Service收到通知之后把json中的title
和body
取出来赋给bestAttemptContent
的title
和body
。
{ "aps":{ "alert":"test test", "mutable-content":1 }, "title": "new title", "body": "new body" }
6、Notification Content
如果通知有attachments,默认情况下长按通知会显示图片或视频,但是我们觉得显示那么大一个图片不美观,而且要有action button,就是下面这种效果,所以要用到Notification Content
。
效果
其实这里没有自定义通知的UI,而是直接把这个View隐藏了。Info.plist
中UNNotificationExtensionInitialContentSizeRatio
表示view的初始height/width(其他属性参考WWDC),把它设为0.001(不能设为0),在viewDidload
中设置self.preferredContentSize = CGSizeZero;
来隐藏view。
Info.plist
这个Extension可以响应多个category
,而每个category
可以注册自己的action buttons,所以action buttons和customUI view是相互独立的,不过可以通过action buttons更新customUI view。
Action buttons默认的行为会打开APP,由delegate处理响应,使用了Notification Content
后,我们可以在Notification Content
直接处理响应而不用打开APP,也可以forward打开APP由delegate处理。
5、真机调试
代码写得差不多了,那就开始调试了。Extension调试过程中有时会遇到Could not attach to process ID
错误。
Could not attach to process ID
有时重启Xcode能解决,有时不能解决,这时候有一个方法,这个窗口弹出之后点OK
,接着点Debug > Attach to Process > 你的Extension
,这时候就能捕获断点了。
6、提交TestFlight
测试过了准备提交TestFlight,结果校验出错了。
Application Loader
错误信息很明显,Extension.appex中包含了Frameworks文件夹。如果Extension使用了Cocoapods,Cocoapods会创建这个文件夹,实际没什么用。解决办法就是在Build Phases
最后增加一个Build Phase
,执行一段shell脚本把Frameworks文件夹删掉。
cd "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/"if [[ -d "Frameworks" ]]; thenrm -fr Frameworksfi
文章转自 zhao0的简书