在今年(16年美國時間9月7日)北京時間9月8日凌晨一點,蘋果發布會不僅發布了新版iPhone7及7Plus。同時也發布了iOS10.隨后Xcode也進行了版本更新。下面講述下使用Xcode8時遇到的各種問題。
1、權限以及相關設置
iOS10系統下調用系統相冊、相機功能,或者蘋果健康都會遇到閃退的情況,
調用系統相冊報錯描述如下:
This app has crashed because it attempted to access privacy-sensitive data without a usage description.The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data
解決辦法(fix method):
在info.plist —Source Code中添加
UsageDescription相關的key, 描述字符串自己隨意填寫就可以,但是一定要填寫,不然會引發包無效的問題,導致上傳打包后構建版本一直不顯示。
如果不起作用,可以請求后臺權限,類似于這樣:
或者在info.plist—Property List中添加
輸入? Privacy
部分
麥克風權限:Privacy - Microphone Usage Description
通訊錄權限: Privacy - Contacts Usage Description
藍牙權限:Privacy - Bluetooth Peripheral Usage Description
語音轉文字權限:Privacy - Speech Recognition Usage Description
日歷權限:Privacy - Calendars Usage Description
定位權限:Privacy - Location When In Use Usage Description
定位權限: Privacy - Location Always Usage Description
定位的需要這么寫,防止上架被拒。
2、代碼注釋不能用的解決辦法
這個是因為蘋果解決xcode ghost,把插件屏蔽了。
解決辦法(fix method):
打開終端,命令運行:sudo /usr/libexec/xpccachectl
重啟電腦后生效
注意:Xcode8內置了開啟注釋的功能:
Add Documentation
快捷鍵的設置:
Xcode-> Preferences -> Key Bindings
Documentation
三方插件解決辦法(fix method):
但是看到文章最后的解釋,我們知道如果用插件的話,可能安全上會有問題、并且提交審核會被拒絕,所以建議大家還是不要用了,解決辦法總是有的,比如在Xcode中添加注釋的代碼塊也是很方便的。
3.屏蔽雜亂無章的bug
解決辦法(fix method):
Edit Scheme-> Run -> Arguments,
在Environment Variables里邊添加
OS_ACTIVITY_MODE = Disable
————這種方法會屏蔽掉真機的NSLog,解決方法請等待————
Edit Scheme
4.UIStatusBar方法過期:
解決辦法(fix method):
//屬性&&方法@property(nonatomic,readonly)UIStatusBarStylepreferredStatusBarStyleNS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;// Defaults to UIStatusBarStyleDefault@property(nonatomic,readonly)BOOLprefersStatusBarHiddenNS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;// Defaults to NO- (UIStatusBarStyle)preferredStatusBarStyleNS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;// Defaults to UIStatusBarStyleDefault- (BOOL)prefersStatusBarHiddenNS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;// Defaults to NO// Override to return the type of animation that should be used for status bar changes for this view controller. This currently only affects changes to prefersStatusBarHidden.- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarAnimationFade
//可以這樣寫- (UIStatusBarStyle)preferredStatusBarStyle {returnUIStatusBarStyleDefault;}
5.label中的文字顯示不全
用Xcode 8和Xcode 7.3
分別測試了下,如下圖:
Xcode 8
Xcode 7
創建一個Label然后讓它自適應大小,字體大小都是17最后輸出的寬度是不一樣的,我們再看一下,下面的數據就知道為什么升iOS 10之后App中有的文字顯示不全了:
發現英文字母沒有問題,只有漢字有問題。目前只有一個一個修改控件解決這個問題。
解決辦法(fix method):
UILabel*myLabel = [UILabelnew];/*UIFont 的preferredFontForTextStyle: 意思是指定一個樣式,并讓字體大小符合用戶設定的字體大小。 */myLabel.font=[UIFontpreferredFontForTextStyle:UIFontTextStyleHeadline];/*
Indicates whether the corresponding element should automatically update its font when the device’s UIContentSizeCategory is changed.
For this property to take effect, the element’s font must be a font vended using +preferredFontForTextStyle: or +preferredFontForTextStyle:compatibleWithTraitCollection: with a valid UIFontTextStyle.
*///是否更新字體的變化myLabel.adjustsFontForContentSizeCategory=YES;
6.使用Xib awakeFromNib的警告問題
在Xcode 8之前我們使用Xib初始化- (void)awakeFromNib {}都是這么寫也沒什么問題,但是在Xcode 8會有如下警告:
如果不喜歡這個警告的話,應該明確的加上[super awakeFromNib];
7.判斷系統版本
oc
//值為10.0[[UIDevicecurrentDevice] systemVersion]
if([[NSProcessInfoprocessInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){.majorVersion=9,.minorVersion=1,.patchVersion=0}]) {NSLog(@"Hello from > iOS 9.1");}if([NSProcessInfo.processInfoisOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9,3,0}]) {NSLog(@"Hello from > iOS 9.3");}
if(NSFoundationVersionNumber>NSFoundationVersionNumber_iOS_9_0) {//dostuffforiOS9andnewer}else{//dostuffforolder versions than iOS9}
swift
ifNSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion:10, minorVersion:0, patchVersion:0)){// 代碼塊}
if#available(iOS10.0, *) {// 代碼塊}else{// 代碼塊}
8.ATS的問題
iOS 9中默認非HTTPS的網絡是被禁止的,當然我們也可以把NSAllowsArbitraryLoads設置為YES禁用ATS。不過iOS 10從2017年1月1日起蘋果不允許我們通過這個方法跳過ATS
,也就是說強制我們用HTTPS,如果不這樣的話提交App可能會被拒絕。但是我們可以通過NSExceptionDomains來針對特定的域名開放HTTP可以容易通過審核。
參考學習文章如下:關于 iOS 10 中 ATS 的問題
9.Xib文件的注意事項
使用Xcode8打開xib文件后,會出現下圖的提示:
Choose Device
大家選擇Choose Device即可。
之后大家會發現布局啊,frame亂了,只需要更新一下frame即可。如下圖
update frame
注意:如果按上面的步驟操作后,在用Xcode7打開Xib會報一下錯誤,
Xcode 8.0 or later
解決辦法:右鍵Xib文件->Open As Source Code刪除下面的
這句話,以及把< document >中的toolsVersion和< plugIn >中的version改成你正常的xib文件中的值,不過不建議這么做,在Xcode8出來后,希望大家都快速上手,全員更新。這就跟Xcode5到Xcode6一樣,有變動,但是還是要盡早學習,盡快適應喲!
—————————————我是分割線—————————————
二、改動
1.UIColor 新增方法
在iOS 10蘋果官方建議我們使用sRGB,因為它性能更好,色彩更豐富。如果你自己為UIColor寫了一套分類的話也可嘗試替換為sRGB,UIColor類中新增了兩個Api如下:
+ (UIColor*)colorWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alphaNS_AVAILABLE_IOS(10_0);- (UIColor*)initWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alphaNS_AVAILABLE_IOS(10_0);
2.真彩色的顯示
真彩色的顯示會根據光感應器來自動的調節達到特定環境下顯示與性能的平衡效果,如果需要這個功能的話,可以在info.plist-Source Code里配置:
UIWhitePointAdaptivityStyle
它有五種取值,分別是:UIWhitePointAdaptivityStyleStandard// 標準模式UIWhitePointAdaptivityStyleReading// 閱讀模式UIWhitePointAdaptivityStylePhoto// 圖片模式UIWhitePointAdaptivityStyleVideo// 視頻模式UIWhitePointAdaptivityStyleStandard// 游戲模式
也就是說如果你的項目是閱讀類的,就選擇UIWhitePointAdaptivityStyleReading這個模式,五種模式的顯示效果是從上往下遞減,也就是說如果你的項目是圖片處理類的,你選擇的是閱讀模式,給選擇太好的效果會影響性能.
3.UITextContentType
// The textContentType property is to provide the keyboard with extra information about the semantic intent of the text document.@property(nonatomic,copy)UITextContentTypetextContentTypeNS_AVAILABLE_IOS(10_0);// default is nil
在iOS 10UITextField添加了textContentType枚舉,指示文本輸入區域所期望的語義意義。
使用此屬性可以給鍵盤和系統信息,關于用戶輸入的內容的預期的語義意義。例如,您可以指定一個文本字段,用戶填寫收到一封電子郵件確認uitextcontenttypeemailaddress。當您提供有關您期望用戶在文本輸入區域中輸入的內容的信息時,系統可以在某些情況下自動選擇適當的鍵盤,并提高鍵盤修正和主動與其他文本輸入機會的整合。
4. UIRefreshControl的使用
在iOS 10 中, UIRefreshControl可以直接在UICollectionView和UITableView中使用,并且脫離了UITableViewController.現在RefreshControl是UIScrollView的一個屬性.使用方法:
UIRefreshControl*refreshControl = [[UIRefreshControlalloc] init];[refreshControl addTarget:selfaction:@selector(loadData) forControlEvents:UIControlEventValueChanged]; collectionView.refreshControl= refreshControl;
5.Notification(通知)
自從Notification被引入之后,蘋果就不斷的更新優化,但這些更新優化只是小打小鬧,直至現在iOS 10開始真正的進行大改重構,這讓開發者也體會到UserNotifications的易用,功能也變得非常強大。
iOS 9 以前的通知
在調用方法時,有些方法讓人很難區分,容易寫錯方法,這讓開發者有時候很苦惱。
應用在運行時和非運行時捕獲通知的路徑還不一致。
應用在前臺時,是無法直接顯示遠程通知,還需要進一步處理。
已經發出的通知是不能更新的,內容發出時是不能改變的,并且只有簡單文本展示方式,擴展性根本不是很好。
iOS 10 開始的通知
所有相關通知被統一到了UserNotifications.framework框架中。
增加了撤銷、更新、中途還可以修改通知的內容。
通知不在是簡單的文本了,可以加入視頻、圖片,自定義通知的展示等等。
iOS 10相對之前的通知來說更加好用易于管理,并且進行了大規模優化,對于開發者來說是一件好事。
iOS 10開始對于權限問題進行了優化,申請權限就比較簡單了(本地與遠程通知集成在一個方法中)。
iOS 10 通知學習相關資料:
活久見的重構 - iOS 10 UserNotifications 框架解析
WWDC2016 Session筆記 - iOS 10 推送Notification新特性
6.UICollectionViewCell
在iOS 10 之前,UICollectionView上面如果有大量cell,當用戶活動很快的時候,整個UICollectionView的卡頓會很明顯,為什么會造成這樣的問題,這里涉及到了iOS 系統的重用機制,當cell準備加載進屏幕的時候,整個cell都已經加載完成,等待在屏幕外面了,也就是整整一行cell都已經加載完畢,這就是造成卡頓的主要原因,專業術語叫做:掉幀.要想讓用戶感覺不到卡頓,我們的app必須幀率達到60幀/秒,也就是說每幀16毫秒要刷新一次.
iOS 10 之前UICollectionViewCell的生命周期是這樣的:
用戶滑動屏幕,屏幕外有一個cell準備加載進來,把cell從reusr隊列拿出來,然后調用prepareForReuse方法,在這個方法里面,可以重置cell的狀態,加載新的數據;
繼續滑動,就會調用cellForItemAtIndexPath方法,在這個方法里面給cell賦值模型,然后返回給系統;
當cell馬上進去屏幕的時候,就會調用willDisplayCell方法,在這個方法里面我們還可以修改cell,為進入屏幕做最后的準備工作;
執行完willDisplayCell方法后,cell就進去屏幕了.當cell完全離開屏幕以后,會調用didEndDisplayingCell方法.
iOS 10 UICollectionViewCell的生命周期是這樣的:
用戶滑動屏幕,屏幕外有一個cell準備加載進來,把cell從reusr隊列拿出來,然后調用prepareForReuse方法,在這里當cell還沒有進去屏幕的時候,就已經提前調用這個方法了,對比之前的區別是之前是cell的上邊緣馬上進去屏幕的時候就會調用該方法,而iOS 10 提前到cell還在屏幕外面的時候就調用;
在cellForItemAtIndexPath中創建cell,填充數據,刷新狀態等操作,相比于之前也提前了;
用戶繼續滑動的話,當cell馬上就需要顯示的時候我們再調用willDisplayCell方法,原則就是:何時需要顯示,何時再去調用willDisplayCell方法;
當cell完全離開屏幕以后,會調用didEndDisplayingCell
方法,跟之前一樣,cell會進入重用隊列.在iOS 10 之前,cell只能從重用隊列里面取出,再走一遍生命周期,并調用cellForItemAtIndexPath
創建或者生成一個cell.在iOS 10 中,系統會cell保存一段時間,也就是說當用戶把cell滑出屏幕以后,如果又滑動回來,cell不用再走一遍生命周期了,只需要調用willDisplayCell
方法就可以重新出現在屏幕中了.iOS 10 中,系統是一個一個加載cell的,二以前是一行一行加載的,這樣就可以提升很多性能;
iOS 10 新增加的Pre-Fetching預加載
這個是為了降低UICollectionViewCell在加載的時候所花費的時間,在 iOS 10 中,除了數據源協議和代理協議外,新增加了一個UICollectionViewDataSourcePrefetching
協議,這個協議里面定義了兩個方法:
- (void)collectionView:(UICollectionView*)collectionView prefetchItemsAtIndexPaths:(NSArray *)indexPathsNS_AVAILABLE_IOS(10_0);- (void)collectionView:(UICollectionView*)collectionView cancelPrefetchingForItemsAtIndexPaths:(NSArray *)indexPathsNS_AVAILABLE_IOS(10_0);
在ColletionView prefetchItemsAt indexPaths這個方法是異步預加載數據的,當中的indexPaths數組是有序的,就是item接收數據的順序;CollectionView cancelPrefetcingForItemsAt indexPaths這個方法是可選的,可以用來處理在滑動中取消或者降低提前加載數據的優先級.注意:這個協議并不能代替之前讀取數據的方法,僅僅是輔助加載數據.Pre-Fetching預加載對UITableViewCell同樣適用.
原文/七州小槑(簡書作者)
原文鏈接:http://www.lxweimin.com/p/90d5323cf510
著作權歸作者所有,轉載請聯系作者獲得授權,并標注“簡書作者”。