適配iOS9

適配iOS9

前言:2015年9月8日,蘋果宣佈iOS 9操作系統的正式版在太平洋時間9月16日正式推出,北京時間9月17日凌晨1點推送。新的iOS 9系統比iOS8更穩定,功能更全面,而且還更加開放。iOS9加入了更多的新功能,包括更加智能的Siri,新加入的省電模式。iOS9爲開發者提供5000個全新的API等。而對於開發者來說,首當其衝的則是iOS9的適配問題。下面小結一下ios9適配問題:

https 和 http 網絡:

  • 在iOS9下,系統默認會攔截對http協議接口的訪問,因此無法獲取http協議接口的數據。如果你的項目用的是http協議,而不做處理的話,那絕對是要崩潰的。
  • 解決方案1:暫時退回http協議。具體做法爲:在項目的info.plist中添加一個Key:NSAppTransportSecurity,類型爲字典類型。然後給它添加一個Key:NSAllowsArbitraryLoads,類型爲Boolean類型,值爲YES; 解決方案2:設置域。可以簡單理解成,把不支持https協議的接口設置成http的接口。
    具體方法:
    1)、在項目的info.plist中添加一個Key:NSAppTransportSecurity,類型爲字典類型。

    2)、然後給它添加一個NSExceptionDomains,類型爲字典類型;

    3)、把需要的支持的域添加給NSExceptionDomains。其中域作爲Key,類型爲字典類型。

    4)、每個域下面需要設置3個屬性:NSIncludesSubdomains、

    NSExceptionRequiresForwardSecrecy、NSExceptionAllowsInsecureHTTPLoads。均爲

    Boolean類型,值分別爲YES、NO、YES。

  • 詳情:爲了強制增強數據訪問安全, iOS9 默認會把 所有的http請求 所有從NSURLConnection 、 CFURL 、 NSURLSession發出的 HTTP 請求,都改爲 HTTPS 請求:iOS9.x-SDK編譯時,默認會讓所有從NSURLConnection 、 CFURL 、 NSURLSession發出的 HTTP 請求統一採用TLS 1.2 協議。因爲 AFNetworking 現在的版本底層使用了 NSURLConnection ,衆多App將被影響(基於iOS8.x-SDK的App不受影響)。服務器因此需要更新,以解析相關數據。如不更新,可通過在 Info.plist 中聲明,倒退回不安全的網絡請求。而這一做法,官方文檔稱爲ATS,全稱爲App Transport Security,是iOS9的一個新特性。

Bitcode:

  • iOS 9新建項目默認需要支持bitcode,而不支持bitcode的SDK會導致無法編譯運行。
  • 解決方案1:暫時關閉對bitcode的支持 解決方案2:移除不支持bitcode的平臺SDK。
  • 詳情:未來, Watch 應用必須包含 bitcode ,iOS不強制,Mac OS不支持。

    bitcode 是被編譯程序的一種中間形式的代碼。包含 bitcode 配置的程序將會在 App Store 上被編譯和鏈接。 bitcode 允許蘋果在後期重新優化我們程序的二進制文件,而不需要我們重新提交一個新的版本到 App Store 上。當我們提交程序到 App Store上時, Xcode 會將程序編譯爲一箇中間表現形式( bitcode )。然後 App store 會再將這個 bitcode 編譯爲可執行的64位或32位程序。
    App Thinning 官方文檔解釋如下:

    The App Store and operating system optimize the installation of iOS and watchOS apps by tailoring app delivery to the capabilities of the user’s particular device, with minimal footprint. This optimization, called app thinning, lets you create apps that use the most device features, occupy minimum disk space, and accommodate future updates that can be applied by Apple. Faster downloads and more space for other apps and content provides a better user experience.
    開發者都知道,當前 iOS App 的編譯打包方式是把適配兼容多個設備的執行文件及資源文件合併一個文件,上傳和下載的文件則包含了所有的這些文件,導致佔用較多的存儲空間。
    
    App Thinning是一個關於節省iOS設備存儲空間的功能,它可以讓iOS設備在安裝、更新及運行App等場景中僅下載所需的資源,減少App的佔用空間,從而節省設備的存儲空間。
    
    根據Apple官方文檔的介紹,App Thinning主要有三個機制:
    
    Slicing
    
    開發者把App安裝包上傳到AppStore後,Apple服務會自動對安裝包切割爲不同的應用變體(App variant),當用戶下載安裝包時,系統會根據設備型號下載安裝對應的單個應用變體。
    
    On-Demand Resources
    
    ORD(隨需資源)是指開發者對資源添加標籤上傳後,系統會根據App運行的情況,動態下載並加載所需資源,而在存儲空間不足時,自動刪除這類資源。
    
    Bitcode 開啓Bitcode編譯後,可以使得開發者上傳App時只需上傳Intermediate Representation(中間件),而非最終的可執行二進制文件。 在用戶下載App之前,AppStore會自動編譯中間件,產生設備所需的執行文件供用戶下載安裝。
    
    (喵大(@onevcat)在其博客 《開發者所需要知道的 iOS 9 SDK 新特性》 中也描述了iOS 9中蘋果在App瘦身中所做的一些改進,大家可以轉場到那去研讀一下。)
    
    其中,Bitcode的機制可以支持動態的進行App Slicing,而對於Apple未來進行硬件升級的措施,此機制可以保證在開發者不重新發布版本的情況下而兼容新的設備。
    
    Bitcode 是一種中間代碼,那它是什麼格式的呢? LLVM 官方文檔有介紹這種文件的格式: LLVM Bitcode File Format 。
    
    如果你的應用也準備啓用 Bitcode 編譯機制,就需要注意以下幾點:
    
    Xcode 7默認開啓 Bitcode ,如果應用開啓 Bitcode,那麼其集成的其他第三方庫也需要是 Bitcode 編譯的包才能真正進行 Bitcode 編譯
    開啓 Bitcode 編譯後,編譯產生的 .app 體積會變大(中間代碼,不是用戶下載的包),且 .dSYM 文件不能用來崩潰日誌的符號化(用戶下載的包是 Apple 服務重新編譯產生的,有產生新的符號文件)
    通過 Archive 方式上傳 AppStore 的包,可以在Xcode的Organizer工具中下載對應安裝包的新的符號文件
    

URL Scheme 白名單:

  • 在iOS 9下涉及到平臺客戶端跳轉,系統會自動到項目info.plist下檢測是否設置平臺Scheme。對於需要配置的平臺,如果沒有配置白名單(白名單上限是50個:),就無法正常跳轉平臺客戶端。因此要支持客戶端的分享和授權等,需要配置Scheme名單。
  • 具體方法:

    1)、在項目的info.plist中添加一LSApplicationQueriesSchemes,類型爲Array。

    2)、然後給它添加一個需要支持的項目,類型爲字符串類型;

  • 詳情:蘋果爲什麼要這麼做?在 iOS9 之前,你可以使用 canOpenURL: 監測用戶手機裏到底裝沒裝微信,裝沒裝微博。但是也有一些別有用心的 App ,這些 App 有一張常用 App 的 URL scheme,然後他們會多次調用canOpenURL: 遍歷該表,來監測用戶手機都裝了什麼 App ,比如這個用戶裝了叫“大姨媽”的App,你就可以知道這個用戶是女性,你就可以只推給這個用戶女性用品的廣告。這是侵犯用戶隱私的行爲。
    這也許就是原因。

StatusBarStyle問題:

  • 如果你升級到Xcode7,編譯的時候是不是會出現這樣的警告呢:

    <Error>: CGContextSaveGState: invalid context 0x0. If you want to see the backtrace,    please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
    <Error>: CGContextTranslateCTM: invalid context 0x0. If you want to see the backtrace,  please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
    <Error>: CGContextRestoreGState: invalid context 0x0. If you want to see the    backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
    
  • 原因是iOS9下有了新的設置狀態欄的方法。具體解決方案:在 Info.plist 文件中做如下修改:
    將 View controller-based status bar appearance 刪除(默認爲 YES),或設置爲YES:
    很顯然我們現在不用這個方法了:[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];怎麼搞呢?認真的童鞋會找到controller裏有新的方法:
    - (UIStatusBarStyle)preferredStatusBarStyle;
    - (UIViewController *)childViewControllerForStatusBarStyle;
    - (void)setNeedsStatusBarAppearanceUpdate
    如果你想設置狀態欄爲白色,那麼你只需在controller裏重寫:

    -(UIStatusBarStyle)preferredStatusBarStyle
    {
        return UIStatusBarStyleLightContent;
    }
    

    記得要 clean 下或者刪除應用程序重新運行

    然而,我們的項目往往是navigationcontroller構成的,但是上面的三個新方法卻是viewcontroller的方法,所以你必須這樣

        - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
    }
    

    我們也可以用類別來實現:navigationcontroller沒有preferredStatusBarStyle方法,那麼就用類別給navigationcontroller加一下羅。

    .h文件:
    
    
    #import <UIKit/UIKit.h>
    
    @interface UINavigationController (StatusBarStyle)
    
    @end
    
    
    .m文件:
    
    
    #import "UINavigationController+StatusBarStyle.h"
    
    @implementation UINavigationController (StatusBarStyle)
    
    - (UIStatusBarStyle)preferredStatusBarStyle
    {
        return UIStatusBarStyleLightContent;
    }
    
    @end
    

.dSYM 文件引起的警告

  • 這是 debug 編譯時導出符號文件出現的告警。新建的Xcode7工程是不會有這樣的警告的。
  • 解決方案 :
    這裏寫圖片描述

directory not found for option問題

  • Xcode7上你也許會碰到下面這個警告:

  • 原因是:Xcode7將framworks位置改變了。
  • 解決方案:

    點擊項目,選擇 Targets->xxxTests
    選擇build setting ,找到 Frameworks Search Path 或者 Library Search Paths
    刪除
    (SDKROOT)/Developer/Library/Frameworks使 (PLATFORM_DIR)/Developer/Library/Frameworks替換

    這裏寫圖片描述

ipad的多任務 multi tasking

  • 大神說要想適配iPad的多任務,唯一的建議是:棄純代碼,改用storyboard、xib。。然而大神說得輕巧,我的整個工程完完全全的純代碼,不是說改就改的。。但是,當我打包的時候,錯誤就來了:

    ERROR ITMS-90475: "Invalid Bundle. iPad Multitasking support requires launch story board in bundle 'xxxx'."
    ERROR ITMS-90474: "Invalid Bundle. iPad Multitasking support requires these orientations: 'UIInterfaceOrientationPortrait,UIInterfaceOrientationPortraitUpsideDown,UIInterfaceOrientationLandscapeLeft,UIInterfaceOrientationLandscapeRight'. Found 'UIInterfaceOrientationPortrait' in bundle 'xxxx'."
    

    既然這樣了,想了想,我的項目裏沒有用到分屏顯示呀,那就暫且關掉多任務羅:
    這裏寫圖片描述

iOS9 下使用 Masonry 會引起崩潰的一種情況

  • 純代碼的項目,我們很喜歡用Masonry來進行適配。我們在使用時候一直將 leading 與 left 劃爲等號,這樣做在 iOS8(及以前)上是正常的,但在 iOS9 上這樣的觀念可能會引起崩潰,比如:

     make.left.equalTo(self.mas_leading).offset(15);
    
    應該爲:
     make.left.equalTo(self.mas_left).offset(15);
    
     同理 mas_training 也需要改爲right
    

iOS9新特性-更靈活的後臺定位

  • 【iOS9在定位的問題上,有一個壞消息一個好消息】壞消息:如果不適配iOS9,就不能偷偷在後臺定位!好消息:將允許出現這種場景:同一App中的多個location manager:一些只能在前臺定位,另一些可在後臺定位,並可隨時開啓或者關閉特定location manager的後臺定位。

  • 如何偷偷在後臺定位:請求後臺定位權限:

     // 1. 實例化定位管理器
    _locationManager = [[CLLocationManager alloc] init];
    // 2. 設置代理
    _locationManager.delegate = self;
    // 3. 定位精度
    [_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    // 4.請求用戶權限:分爲:⓵只在前臺開啓定位⓶在後臺也可定位,
    //注意:建議只請求⓵和⓶中的一個,如果兩個權限都需要,只請求⓶即可,
    //⓵⓶這樣的順序,將導致bug:第一次啓動程序後,系統將只請求⓵的權限,⓶的權限系統不會請求,只會在下一次啓動應用時請求⓶
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) {
        //[_locationManager requestWhenInUseAuthorization];//⓵只在前臺開啓定位
        [_locationManager requestAlwaysAuthorization];//⓶在後臺也可定位
    }
    // 5.iOS9新特性:將允許出現這種場景:同一app中多個location manager:一些只能在前臺定位,另一些可在後臺定位(並可隨時禁止其後臺定位)。
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
        _locationManager.allowsBackgroundLocationUpdates = YES;
    }
    // 6. 更新用戶位置
    [_locationManager startUpdatingLocation];
    
  • 但是如果照着這種方式嘗試,而沒有配置Info.plist,100%你的程序會崩潰掉,並報錯:

    *** Assertion failure in -[CLLocationManager setAllowsBackgroundLocationUpdates:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/CoreLocationFramework_Sim/CoreLocation-1808.1.5/Framework/CoreLocation/CLLocationManager.m:593
    

    要將 Info.plist 配置如下: enter image description here

    這裏寫圖片描述

發佈了25 篇原創文章 · 獲贊 11 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章