一、Widget入門簡介
widget 工程創建開發簡介
http://www.lxweimin.com/p/ca3e11d7686c
widget簡介及證書配置
http://www.cocoachina.com/ios/20161114/18078.html
適配、展開、折疊
http://www.lxweimin.com/p/9b3d06236d19
上線后無widget功能
http://blog.csdn.net/baidu_31683691/article/details/53115690
如果不需要引入第三方庫的話,由以上帖子就可以入門基本的Widget開發了,只需要簡單注意下
1、證書的配置:
需要新建Identifiers以及后續的開發和發布兩個證書,注意在Identifiers里的Application?Services需要打開App Groups(兩個相同App Groups的應用可以共用某沙盒里的數據),而在Xcode中需要在Targets-項目-Capabilities里打開。
2、iOS8/iOS10 Widget的適配(iOS8和iOS9的應該沒有區別):
①、iOS8下沒有折疊和展開功能,默認的Widget高度為self.preferredContentSize設置的高度。
②、iOS8下所有組件默認右移30單位。
③、iOS8下Widget的默認背景為黑色的磨砂效果,所以文字基本為淺白色,而iOS10則為白色磨砂效果,文字則需要改為深黑色。有些應用未作適配,所以在Widget列表里挺違和的。
二、Widget通過cocoapods導入第三方庫
由之前證書的創建和App Groups的新增權限,隱約可以猜到我們App的主體Target和新建的Today Extension似乎是獨立的兩個應用,由于之前未做過Extension的開發,當我發現這點的時候,也使我在開發Widget時遇到的一系列問題有了合理的解釋,因為這就是倆應用啊。
本來就是倆獨立的應用,這就導致上線打包的時候,你會發現應用包的大小會增加不少,我簡單測了下,我們的原始程序打包后的ipa大小為19.6M,添加widget后的ipa包大小為20.2M,這還是未添加第三方組件的大小(當然這只是我自己的測試,如果有在不增加ipa包大小的前提下導入第三方包的方法,歡迎補充和討論)。
所以如果公司需要上Widget的功能,同時又對ipa包的大小有著嚴格的要求,那么最好提前跟項目負責人說清,因為兩個基本獨立的應用,Widget顯然無法使用主項目已導入的第三方Lib庫。AFNetworking、Masonry這類還好,地圖類SDK的包大小太過驚人,導入后的ipa包至少增加了3M。而我們知道在AppStore里顯示的應用大小,是解壓后來看的,這就導致到達用戶手中的應用大小會增加不少。
順便安利個 iOS安裝包瘦身指南:
http://www.zoomfeng.com/blog/ipa-size-thin.html
回到主線,即通過cocoapods,在Widget里添加第三方SDK,在百度、stackoverflow了眾多已經無效(cocoapods2.0或者Xcode8已修改)的方法后
我使用的辦法就是:
其中use_frameworks! 是因為導入的SDK中包含了swift3.0的第三方庫,猜測這也是我們項目在類擴展中無法像其他帖子里介紹的那樣簡單導入第三方庫且不出任何bug的原因。
其中XXX需要改為你們項目的targets名稱,widget改為你們today extension的target名稱
有細心的吃瓜群眾可能發現了,為何在 def ?end 里只添加了BaiduMapKit和UMengAnalytics呢,前面不是說了AFNetworking和Masonry嗎。
在我的測試過程中,發現在像百度和友盟這種打好包的.framework庫,通過def end可以輕松導入,如果新增AF或者Masonry 則程序會各種報錯,包括但不限于 image not found等問題。
例如:
dyld: Library not loaded: @rpath/AFNetworking.framework/AFNetworking
Referenced from: /private/var/containers/Bundle/Application/016F51DF-7F1F-4702-9098-5B4E4D354677/Air.app/PlugIns/widget.appex/widget
Reason: image not found
根據關鍵詞我在stackoverflow里搜到了這個問答(http://stackoverflow.com/questions/30053144/dyld-library-not-loaded-with-cocoapods-0-37-and-xcode-6-3/30166310#30166310),github里有這個(https://github.com/CocoaPods/CocoaPods/issues/3903)然而根據回答一個一個試,其中包括:
1、設置Optional
2、修改bitcode
3、重啟cocoapods
4、證書配置
5、重啟xcode 電腦 ?s+command+k
6、清理derivedData(注意這一項可能會導致友盟線上統計的本地崩潰定位失效)
7、修改always_embed_swift_standard_libraries
8、添加@executable_path/Frameworks
然而并沒有解決該問題,反而跟滾雪球一樣引起了各種其他的問題,所以也建議大家在開發Widget時,一定要注意備份。
所以我的解決辦法就是.....直接把AF或者Masonry文件拖進Widget里,恩,世界突然安靜了,程序也沒問題了。
三、Widget開發異常總結
最后做個Widget開發過程中遇到的各種異常的總結吧,也歡迎大家提出自己遇到的問題和建議。
1、
- xxxx (3.0) and widget () do not use the same Swift version.
這個問題是項目使用swift版本不一致產生的,每次打開項目時也會遇到Alert提示,在Xcode-Edit-Convert-To Current Swift Syntax里升級swift就行,記得提前備份。
2、
Undefined symbols for architecture arm64
"_OBJC_CLASS_$_MyRequest", referenced from:
objc-class-ref in TodayViewController.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
這是未引入相關文件的問題,如果沒有導入主target的所有pods,建議直接新建文件,并重新命名。
3、直接導入主target的所有pods(也能在widget里使用第三方庫)
直接在project-info-configurations里的debug和release里增加widget的相關lib庫,即把None改為主項目的pods,猜測為直接導入主項目的pods庫,此時cocoapods里的Podfile可以不用def end。而widget可以直接使用主項目的pods庫(無論有沒有.framework),此時打出的包也稍小(小于1m),問題就在于每次pod install / update 都需要重新設置,但是這個設置超出了我的理解范圍,不知道原因,所以發出來大家可以討論下
step1:
step2:
而通過def end 導入的pods庫設置為:
4、
no such module
5、
[!] The `widget [Debug]` target overrides the `OTHER_CFLAGS` build setting defined in `Pods/Target Support Files/Pods-widget/Pods-widget.debug.xcconfig'. This can lead to problems with the CocoaPods installation
這是xcode的設置問題,一般會成對出現(主target和extension)相關的還有
'ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES'
其中修改的地方只有兩處
待續....
--------
由于xcode版本、iOS版本、swift版本、cocoapods版本、不同第三方庫的設置的不同,造成一開始覺著很輕松的widget開發,遇到的問題也越來越多,需要完善和優化的地方也有不少。