iOS十二、iOS十一、iOS十、iOS9常見適配

1、iOS12(Xcode10)javascript

1.一、升級Xcode10後項目報錯css

不容許多個info.plistjava

Xcode10是默認選中的最新的New Build System(Default),在這個編譯系統的環境下,不容許多個info.plistios

解決辦法一:(推薦)c++

把build system切換到 Legacy Build System,換言之就是切換成老的編譯系統,就OK了。git

Xcode->File->Project Settings-> Build System -> Legacy Build System.github

image.png

image.png

解決辦法二:json

刪除其餘info.plist文件。swift

iOS 12移除了libstdc++, 用libc++替代xcode

Xcode10中libstdc++相關的3個庫(libstdc++、libstdc++.六、libstdc++6.0.9)應該都是被完全廢棄了,若是你使用的三方庫中有依賴,請儘快和提供方溝通,告知他們遷移吧。若是本身開發使用,也儘快考慮遷移的事宜吧。

1.二、iPhone XR不支持3D-Touch

OC檢測代碼

1

2

3

if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {

 

}

swift檢測代碼

1

self.traitCollection.forceTouchCapability == .availible

2、iOS11(Xcode9)

2.一、安全區域(SafeArea)

iOS11爲UIViewController和UIView增長了兩個新的屬性safeAreaInsets和safeAreaLayoutGuide

safeAreaInsets 適用於手動計算.

safeAreaLayoutGuide 適用於自動佈局.

1

2

3

4

UIViewController中新增:

- (void)viewSafeAreaInsetsDidChange;

UIView中新增:

- (void)viewSafeAreaInsetsDidChange;

在Storyboard使用Safe Area最低只支持iOS9,iOS8的用戶就要放棄了

image.png

image.png

當UIViewController調用- (void)viewDidLoad時它的全部子視圖的safeAreaInsets屬性都等於UIEdgeInsetsZero。

viewSafeAreaInsetsDidChange的調用時機以下:

 一、viewDidLoad

 二、viewWillAppear

 三、viewSafeAreaInsetsDidChange

 四、viewWillLayoutSubviews

 五、viewDidAppear

只有在調用viewSafeAreaInsetsDidChange後,才能得到view以及viewController的SafeArea(UIEdgeInsets)。所以在viewDidload中根據SafeArea設置界面會有問題。

iPhone X:有導航欄的時候能夠+44

豎屏 safeAreaInsets = (top = 44, left = 0, bottom = 34, right = 0)

橫屏 safeAreaInsets = (top = 0, left = 44, bottom = 21, right = 44)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

#import "Adaptive11VC.h"

static inline UIEdgeInsets sgm_safeAreaInset(UIView *view) {

    if (@available(iOS 11.0, *)) {

        return view.safeAreaInsets;

    }

    return UIEdgeInsetsZero;

}

 

@interface Adaptive11VC ()

@end

@implementation Adaptive11VC

- (void)viewDidLoad {

    [super viewDidLoad];

}

- (void)testSafeArea {

    UIEdgeInsets safeAreaInsets = sgm_safeAreaInset(self.view);

    NSLog(@"safeAreaInsets = %@", NSStringFromUIEdgeInsets(safeAreaInsets));

}

- (void)viewSafeAreaInsetsDidChange {

    [super viewSafeAreaInsetsDidChange];

    [self testSafeArea];

}

@end

2.二、UIScrollView

iOS 11廢棄了UIViewController的automaticallyAdjustsScrollViewInsets屬性,新增了contentInsetAdjustmentBehavior屬性,因此當超出安全區域時系統自動調整了SafeAreaInsets,進而影響了adjustedContentInset,在iOS11中決定tableView內容與邊緣距離的是adjustedContentInset,因此須要設置UIScrollView的contentInsetAdjustmentBehavior屬性。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// 方式一:(不推薦)修改額外的安全區域

if (@available(iOS 11.0, *)) {

    self.additionalSafeAreaInsets = UIEdgeInsetsMake(-44000);

}

else {

    // Fallback on earlier versions

}

// 方式二:(推薦)設置爲不自動調整

if (@available(iOS 11.0, *)) {

    // 做用於指定的UIScrollView

    self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;

    // 做用與全部的UIScrollView

    UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;

}

else {

    self.automaticallyAdjustsScrollViewInsets = NO;

}

2.三、tableview問題

iOS11開始UITableView開啓了自動估算行高,estimatedRowHeight estimatedSectionHeaderHeight estimatedSectionFooterHeight三個高度估算屬性由默認的0變成了UITableViewAutomaticDimension,若是不實現-tableView: viewForFooterInSection: 和 -tableView: viewForHeaderInSection:,那麼estimatedRowHeight estimatedSectionHeaderHeight estimatedSectionFooterHeight三個高度估算屬性由默認的0變成了UITableViewAutomaticDimension,致使高度計算不對,會產生空白。解決方法是實現對應方法或吧這三個屬性設爲0。

2.四、LocalAuthentication 本地認證

本地認證框架提供了從具備指定安全策略(密碼或生物學特徵)的用戶請求身份驗證的功能。例如,要求用戶僅使用Face ID或Touch ID進行身份驗證,可以使用如下代碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

#import <localauthentication localauthentication.h="">

/**

 檢測TouchID是否可用

 */

- (void)checkBiometrics {

    LAContext *context = [[LAContext alloc] init];

    BOOL success = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics

                                        error:nil];

    if ( success ) {

        NSLog(@"can use");

    }

    else {

        NSLog(@"can`t use ");

    }

}

/**

 在驗證TouchID可用的狀況下使用

 */

- (void)excuteBiometrics {

    LAContext *context = [[LAContext alloc] init];

    context.localizedFallbackTitle = @"自定義標題";

    [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics

            localizedReason:@"爲何使用TouchID寫這裏"

                      reply:^(BOOL success, NSError * _Nullable error) {

        if ( success ) {

            // 指紋驗證成功

        }

        else {

            switch (error.code) {

                case LAErrorUserFallback:{

                    NSLog(@"用戶選擇輸入密碼");

                    break;

                }

                case LAErrorAuthenticationFailed:{

                    NSLog(@"驗證失敗");

                    break;

                }

                case LAErrorUserCancel:{

                    NSLog(@"用戶取消");

                    break;

                }

                case LAErrorSystemCancel:{

                    NSLog(@"系統取消");

                    break;

                }

                // 如下三種狀況若是提早檢測TouchID是否可用就不會出現

                case LAErrorPasscodeNotSet:{

                    break;

                }

                case LAErrorTouchIDNotAvailable:{

                    break;

                }

                case LAErrorTouchIDNotEnrolled:{

                    break;

                }

                default:

                    break;

            }

        }

    }];

}</localauthentication>

2.五、啓動圖的適配

方法一:經過LaunchScreen.storyboard方式啓動

方法二:使用Assets中的LaunchImageimage.png

  • 給Brand Assets添加一張1125*2436大小的圖片

    • 打開Assets.xcassets文件夾,找到Brand Assets

    • 右鍵Show in Finder

    • 添加一張1125*2436大小的圖片

  • 修改Contents.json文件,添加以下內容

1

2

3

4

5

6

7

8

9

{

"extent" "full-screen",

"idiom" "iphone",

"subtype" "2436h",

"filename" "1125_2436.png",

"minimum-system-version" "11.0",

"orientation" "portrait",

"scale" "3x"

}

2.六、定位相關

在 iOS 11 中必須支持 When In Use 受權模式(NSLocationWhenInUseUsageDescription),在 iOS 11 中,爲了不開發者只提供請求 Always 受權模式這種狀況,加入此限制,若是不提供When In Use 受權模式,那麼 Always 相關受權模式也沒法正常使用。

若是要支持老版本,即 iOS 11 如下系統版本,那麼建議在 info.plist 中配置全部的 Key(即便

1

2

3

4

5

NSLocationAlwaysUsageDescription 在 iOS 11及以上版本再也不使用):

NSLocationWhenInUseUsageDescription

NSLocationAlwaysAndWhenInUseUsageDescription

NSLocationAlwaysUsageDescription

NSLocationAlwaysAndWhenInUseUsageDescription  // 爲 iOS 11 中新引入的一個 Key。

2.7、iOS11中 UIKit’s Bars 上的變化

3、iOS10(Xcode8)

3.一、(Why?Safe!)插件取消

Xcode8取消了三方插件(不少優秀的插件,原本能夠顯著提升效率)的功能,使用Extension代替

Xcode 8 Extension 推薦

3.二、證書問題

爲了方便用戶來管理,提供Automatically manage signing。須要輸入開發者帳號!若是沒有帳號也不要緊,在下面也能夠選擇Debug、Realease、inHouse模式下對應的證書也能夠!

3.三、隱私數據訪問問題

iOS10,蘋果增強了對隱私數據的保護,要對隱私數據權限作一個適配,iOS10調用相機,訪問通信錄,訪問相冊等都要在info.plist中加入權限訪問描述,否則以前大家的項目涉及到這些權限的地方就會直接crash掉。

解決辦法:

只須要在info.plist添加NSContactsUsageDescription的key, value本身隨意填寫就能夠,這裏列舉出對應的key(Source Code模式下):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

<key>NSPhotoLibraryUsageDescription</key><string>App須要您的贊成,才能訪問相冊</string>

 

<key>NSCameraUsageDescription</key><string>App須要您的贊成,才能訪問相機</string>

 

<key>NSMicrophoneUsageDescription</key><string>App須要您的贊成,才能訪問麥克風</string>

 

<key>NSLocationUsageDescription</key><string>App須要您的贊成,才能訪問位置</string>

 

<key>NSLocationWhenInUseUsageDescription</key><string>App須要您的贊成,才能在使用期間訪問位置</string>

 

<key>NSLocationAlwaysUsageDescription</key><string>App須要您的贊成,才能始終訪問位置</string>

 

<key>NSCalendarsUsageDescription</key><string>App須要您的贊成,才能訪問日曆</string>

 

<key>NSRemindersUsageDescription</key><string>App須要您的贊成,才能訪問提醒事項</string>

 

<key>NSMotionUsageDescription</key><string>App須要您的贊成,才能訪問運動與健身</string>

 

<key>NSHealthUpdateUsageDescription</key><string>App須要您的贊成,才能訪問健康更新 </string>

 

<key>NSHealthShareUsageDescription</key><string>App須要您的贊成,才能訪問健康分享</string>

 

<key>NSBluetoothPeripheralUsageDescription</key><string>App須要您的贊成,才能訪問藍牙</string>

 

<key>NSAppleMusicUsageDescription</key><string>App須要您的贊成,才能訪問媒體資料庫</string>

image.png

3.四、跳轉到app內的隱私數據設置頁面

iOS 10 幹掉了全部系統設置的 URL Scheme,這意味着你不再可能直接跳轉到系統設置頁面(好比 WiFi、蜂窩數據、定位等)。

跳轉方式

方式一:prefs:root=某項服務 適用於 小於 iOS10的系統;

NSURL *url = [NSURL URLWithString:@"prefs:root=WIFI"];

方式二:prefs:root=bundleID 適用於 大於等於iOS8系統,小於iOS10的系統

NSURL *url = [NSURL URLWithString:@"prefs:root=bundleID"];

方式三:UIApplicationOpenSettingsURLString 適用於 大於等於iOS8的系統

NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

// iOS系統版本 >= 10.0

{

    NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];

    if ([[UIApplication sharedApplication] canOpenURL:url]) {

        [[UIApplication sharedApplication] openURL:url];

    }

}

return;

// iOS系統版本 >= 10.0

// But! 不建議這樣作哦,官方文檔中說過:

// `URL is now considered a private API and use will result in app rejection`.

// 雖然是有可能躲過蘋果的檢測,可是蘋果若是發現你這樣用了,app上架是有被拒的風險的.

{

    NSURL *url = [NSURL URLWithString:@"APP-Prefs:root=WIFI"];

    if ([[UIApplication sharedApplication] canOpenURL:url]) {

        if (@available(iOS 10.0, *)) {

            [[UIApplication sharedApplication] openURL:url 

              options:@{} 

    completionHandler:nil];

        else {

            // Fallback on earlier versions

        }

    }

}

// iOS系統版本 < 10.0

{

    NSURL *url = [NSURL URLWithString:@"prefs:root=WIFI"];

    if ([[UIApplication sharedApplication] canOpenURL:url]) {

        [[UIApplication sharedApplication] openURL:url];

    }

}

跳轉目的地

iOS系統版本 <= iOS7 , 只能跳轉到 系統設置頁面

iOS系統版本 >= iOS8 ,支持跳轉到第三方應用的設置界面中。使用prefs:root=bundleID ,bundleID是你第三方應用工程的惟一ID

iOS系統版本 >= iOS10,支持跳轉到本身應用設置,不支持跳轉到系統設置

3.五、字體變化

蘋果的默認字體會隨着iOS系統版本的不一樣而不一樣,iOS10中字體變大了。致使了原來的顯示有問題,會形成...的出現。暫時沒有好的解決辦法,須要本身在一個個適配一下!

3.六、UICollectionViewCell的的優化

在iOS 10 以前,cell只能從重用隊列裏面取出,再走一遍生命週期,並調用cellForItemAtIndexPath建立或者生成一個cell.

在iOS 10 中,系統會cell保存一段時間,也就是說當用戶把cell滑出屏幕之後,若是又滑動回來,cell不用再走一遍生命週期了,只須要調用willDisplayCell方法就能夠從新出如今屏幕中了.

iOS 10 中,系統是一個一個加載cell的,二之前是一行一行加載的,這樣就能夠提高不少性能;

iOS 10 新增長的Pre-Fetching預加載

3.七、UIRefreshControl

在iOS 10 中, UIRefreshControl能夠直接在UICollectionView和UITableView中使用,而且脫離了UITableViewController.如今RefreshControl是UIScrollView的一個屬性.

3.八、UserNotifications(用戶通知)

iOS 10全部相關通知被統一到了UserNotifications.framework框架中。增長了撤銷、更新、中途還能夠修改通知的內容。通知不在是簡單的文本了,能夠加入視頻、圖片,自定義通知的展現等等。

iOS 10相對以前的通知來講更加好用易於管理,而且進行了大規模優化,對於開發者來講是一件好事。

iOS 10開始對於權限問題進行了優化,申請權限就比較簡單了(本地與遠程通知集成在一個方法中)。

4、iOS9(Xcode7)

4.一、Bitcode

Xcode7 默認啓用 Bitcode,可是若是咱們用到的第三方庫編譯時還沒啓用 Bitcode,主工程就會編譯不過。Bitcode 是蘋果 App Thinning 的機制之一,能夠減小安裝包的大小。App store 會將這個 Bitcode 編譯爲可執行的64位或32位程序。

解決辦法一:

最簡單的解決辦法是先把 Bitcode 關掉:把 Build settings - Build Options - Enable Bitcode 改成 NO。image.png

解決辦法二:

移除不支持BitCode的平臺SDK,或者尋找支持BitCode的替代品,或者聯繫SDK方支持BitCode。

4.二、HTTP 請求失敗

iOS9 默認不支持 HTTP 請求,須要改用更安全的 HTTPS(默認用 TLS 1.2)。蘋果還提供了配置,使得全部安全性更低的網絡請求也能使用,解決方案就是在 info.plist 裏面增長如下配置:

1

2

3

4

5

<key>NSAppTransportSecurity</key>

<dict>

    <key>NSAllowsArbitraryLoads</key>

    <true>

</true></dict>

若是複雜一些,還能夠指定白名單域名,聲明所支持 TLS 的最低版本。另外須要注意的是,即便寫了上述配置,在 HTTPS 頁面中,HTTP 的 javascript 或 css 不會被加載,由於蘋果認爲這下降了頁面的安全性。

4.三、canOpenUrl 限制

canOpenUrl 能夠用來判斷用戶是否安裝了某個 APP。也許是出於用戶隱私的考慮,iOS9 上對 canOpenUrl 作了限制,最多隻能對 50 個 scheme 作判斷。若是是用 Xcode7 編譯,須要在 plist 裏面聲明這些 scheme,沒有聲明的會直接返回 NO:

1

2

3

4

5

<key>LSApplicationQueriesSchemes</key>

<array>

    <string>weixin</string>

    <string>wechat</string>

</array>

4.四、UIStatusBar的問題

iOS9中廢棄的方法

1

2

3

4

5

6

7

8

9

// 修改狀態欄的樣式爲白色

// 'setStatusBarStyle(_:animated:)' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle]

UIApplication.shared.setStatusBarStyle(.lightContent, animated: true)

// 隱藏狀態欄

// 'setStatusBarHidden(_:with:)' was deprecated in iOS 9.0: Use -[UIViewController prefersStatusBarHidden]

UIApplication.shared.setStatusBarHidden(truewith: .fade)

複製代碼用下面兩個方法替換

-[UIViewController preferredStatusBarstyle]

-[UIViewController preferredStatusBarHidden]

相關文章
相關標籤/搜索