iOS知識點

[TOC]

016

獲取iOS設備uuid, 獲取App bundleid

?  ~ idevice_id -l
a82fecc1d3f1628f85e5055e238d8515f23624da

# 需要安裝ideviceinstaller: brew install ideviceinstaller
?  ~ ideviceinstaller -l
Total: 45 apps
com.tencent.xin - 微信 7.0.4.40
com.wmc-china.MemoryChampionshipsHD - 腦力大師 1.0.8
com.reederapp.iOS - Reeder 4000.39.01
com.xk72.Charles - Charles 95
is.workflow.my.app - 快捷指令 784
com.kapeli.dash.ios - Dash 400
com.sugarmo.ScrollClip - Picsew 2911
com.apple.TestFlight - TestFlight 6
com.netease.mailmasterpro - 網易郵箱大師 1429
com.baidu.map - 百度地圖 10.15.0.7
com.moke.Annotable - Annotable 150

015


代碼閱讀target-action

(lldb) e id $view = (id) 0x7fbd71432590

(lldb) po [$view  allTargets]
{(
    <lldb.ViewController: 0x7feff2d67330>
)}

(lldb) po [$button actionsForTarget:(id)0x7feff2d67330 forControlEvent:0]

014


自動打包遇到的問題

當Team:Personal Team is not enrolled in the Apple Developer Program時,下面的命令導出ipa失敗
失敗原因${options_plist}所指定的文件中method字段寫為了ad-hoc,修改為development就ok了

xcodebuild -exportArchive -archivePath ${archive_path} -exportPath ${ipa_path} -exportOptionsPlist ${options_plist}

上面命令的失敗輸出:
error: exportArchive: No signing certificate "iOS Distribution" found

Error Domain=IDECodesignResolverErrorDomain 
Code=1 "No signing certificate "iOS Distribution" found" 
UserInfo={
IDEProvisioningError_UserInfoKey_IDEProvisioningErrorPlatform=com.apple.platform.iphoneos, 
IDEProvisioningError_UserInfoKey_IDEProvisioningErrorAction=5, 
NSLocalizedRecoverySuggestion=No "iOS Distribution" signing certificate matching team ID "P9DNHPPVMB" with a private key was found.,
IDEProvisioningError_UserInfoKey_IDEProvisioningErrorSpecifier=iOS Distribution,
IDEProvisioningError_UserInfoKey_IDEProvisioningErrorTeam=<IDEProvisioningBasicTeam: 0x7f884413e0c0; teamID='P9DNHPPVMB', teamName='(null)'>,
NSLocalizedDescription=No signing certificate "iOS Distribution" found
}
Team:Personal Team is not enrolled in the Apple Developer Program.png

-exportOptionsPlist可以指向一個plist文件,文件內容大致如下:

plist文件.png

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>teamID</key>
    <string>P9DNHPPVMB</string>
    <key>method</key>
    <string>ad-hoc</string>
    <key>uploadSymbols</key>
    <true/>
    <key>provisioningProfiles</key>
    <dict>
        <key>com.jason.abcdefg</key>
        <string>6ce1bd8e-21b4-43c0-a00c-5aa86e131b45</string>
    </dict>
</dict>
</plist>

<key>provisioningProfiles</key> :
xxxx.mobileprovision[6ce1bd8e-21b4-43c0-a00c-5aa86e131b45.mobileprovision]
Xcode把Profiles下載到如下目錄:
~/Library/MobileDevice/Provisioning Profiles

mobileprovision是二進制文件無法查看, 可以用如果下的命令查看文件內容

security cms -D -i 6ce1bd8e-21b4-43c0-a00c-5aa86e131b45.mobileprovision
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>AppIDName</key>
    <string>XC com jason abcdefg</string>
    <key>ApplicationIdentifierPrefix</key>
    <array>
    <string>P9DNHPPVMB</string>
    </array>
    <key>DeveloperCertificates</key>
    <array>
        <data>MIIFmjCCBIKgAwIBAgIISlCOHuhedtMwDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgwNzIyMjM0NzMzWhcNMTkwNzIyMjM0NzMzWjCBjTEaMBgGCgmSJomT8ixkAQEMCk5OTDNENUg4MjIxOzA5BgNVBAMMMmlQaG9uZSBEZXZlbG9wZXI6IHpob3VqaWVfOTAzQDE2My5jb20gKFRDRExWRkVRSEopMRMwEQYDVQQLDApQOUROSFBQVk1CMRAwDgYDVQQKDAfmnbAg5ZGoMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPer0ggVn8D+jjuhHTxyFex3bk1Dp+Oxz7115mFwmwKwn0w7/RFFg87NpL3nGZA5FPpLdJfDPdZiVoNMcKA5Tl+KQRH9FYXENtli/Bn2/VEt9Cv8QQH71h26/U/mKtkBZCtxP4nR52v36naheUCS+2vB9UUy0Ndm2FnobegD8biJlJqtNFVYXTAQ+F/kJEnuLwWcr/uWmq4iteUvQxIOBkGlguw2g6Auw7/TjA1/6HGPaVsX3Tpz/M7A2I7nUB6QU54Z+sGnuMSJbelzwx8o1UyXTzgmuxaPMPUyARUETcDBKZLQ0QLNAkUCNpl1Ss6zv5trE06mbelquKBXp3BdUncCAwEAAaOCAfEwggHtMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUiCcXCam2GGCL7Ou69kdZxVJUo7cwPwYIKwYBBQUHAQEEMzAxMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5hcHBsZS5jb20vb2NzcDAzLXd3ZHIwMTCCAR0GA1UdIASCARQwggEQMIIBDAYJKoZIhvdjZAUBMIH+MIHDBggrBgEFBQcCAjCBtgyBs1JlbGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMDYGCCsGAQUFBwIBFipodHRwOi8vd3d3LmFwcGxlLmNvbS9jZXJ0aWZpY2F0ZWF1dGhvcml0eS8wFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFHuh/bXHzpKtVf6EXpIIYrQ2j19hMA4GA1UdDwEB/wQEAwIHgDATBgoqhkiG92NkBgECAQH/BAIFADANBgkqhkiG9w0BAQsFAAOCAQEAo9AA9R9Lg6f77WY4n51KgP8MMHaEdDKmuji/sdHVhqCpMqfGdcVmweE2lp4M38g/SD2diOFL4YhXdlwG3e1jc68L8GIvfT+AeaAk3G2K7D6Ew6iR4vmAmWTUKbb8OIN7a5KGALKABfwAEDHynJnN+x2n7yCsQtlf1pF8vkYgmewDAeBPqc2ruq9WvxIcRDsAixEr0/f08zzohHSK0omAYSuKTd85UqRnZ1QUSbrDIG2U+H0qiS+0Qw4xyCHjlqtWRbMaoEppowcjgah8Llnp0Lel56mW0l4iMZdbHlRpsDbA+gX1tPeJN5ztvnNEjawDDQ8tT+U3RW7OcWrcIq43Cg==</data>
    </array>
    <key>Entitlements</key>
    <dict>
        <key>keychain-access-groups</key>
        <array>
            <string>P9DNHPPVMB.*</string>
        </array>
        <key>get-task-allow</key>
        <true/>
        <key>application-identifier</key>
        <string>P9DNHPPVMB.com.jason.abcdefg</string>
        <key>com.apple.developer.team-identifier</key>
        <string>P9DNHPPVMB</string>

    </dict>
    <key>ExpirationDate</key>
    <date>2018-11-01T11:22:49Z</date>
    <key>Name</key>
    <string>iOS Team Provisioning Profile: com.jason.abcdefg</string>
    <key>ProvisionedDevices</key>
    <array>
        <string>a82fecc1d3f1628f85e5055e238d8515f23624da</string>
    </array>
    <key>TeamIdentifier</key>
    <array>
        <string>P9DNHPPVMB</string>
    </array>
    <key>TeamName</key>
    <string>&#26480; &#21608;</string>
    <key>UUID</key>
    <string>6ce1bd8e-21b4-43c0-a00c-5aa86e131b45</string>
</dict>
</plist>

Xcode 10生成的ExportOptions.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>compileBitcode</key>
    <true/>
    <key>method</key>
    <string>development</string>
    <key>signingStyle</key>
    <string>automatic</string>
    <key>stripSwiftSymbols</key>
    <true/>
    <key>teamID</key>
    <string>P9DNHPPVMB</string>
    <key>thinning</key>
    <string>&lt;none&gt;</string>
</dict>
</plist>
ipa目錄結構.png

013


iOS 中的數組排序操作

NSLiteralSearch
區分 同一個字符(如日文的片假字)的半角與全角狀態[半角狀態 > 全角狀態]

NSWidthInsensitiveSearch
不區分 同一個字符(如日文的片假字)的半角與全角狀態[半角狀態 = 全角狀態]
同時指定兩個時,NSWidthInsensitiveSearch 比 NSLiteralSearch 的優先級高,綜合起來的結果: [半角狀態 = 全角狀態]

NSForcedOrderingSearch
NSForcedOrderingSearch 的優先級最高

參考iOS 中的數組排序操作

012


工作線程中銷毀對象

對象的銷毀雖然消耗資源不多,但累積起來也是不容忽視的。通常當容器類持有大量對象時,其銷毀時的資源消耗就非常明顯。同樣的,如果對象可以放到后臺線程去釋放,那就挪到后臺線程去。這里有個小 Tip:把對象捕獲到 block 中,然后扔到后臺隊列去隨便發送個消息以避免編譯器警告,就可以讓對象在后臺線程銷毀了

NSArray *tmp = self.array;
self.array = nil;
dispatch_async(queue, ^{
    [tmp class];
});

引用自iOS 保持界面流暢的技巧

011


beginIgnoringInteractionEvents

UIApplication.shared.beginIgnoringInteractionEvents()
pvc.setViewControllers([vc], direction: dir, animated: true) { _ in 
  UIApplication.shared.endIgnoringInteractionEvents()         
}

In that code, I turn off user interaction when the page animation starts and turn it back on when the animation ends. The reason is that otherwise we can crash (or get into an incoherent state) if the user taps during the animation.

applicationWillTerminate:不一定被調用

For apps that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the app.
For apps that support background execution, this method is generally not called when the user quits the app because the app simply moves to the background in that case. However, this method may be called in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason

像閱讀類應用如:咪咕閱讀、掌閱、QQ閱讀有朗讀功能,開啟了Background Modes:


朗讀功能開啟Background Modes.png

開啟后進入后臺一段時間,app被殺掉,applicationWillTerminate就不一定被調用

010


UIScrollView的scrollRectToVisible: animated:方法應用

UIScrollView的scrollRectToVisible: animated:NO 可以使用UIScrollView立即停止滑動,而用設置contentOffset的方法,還會滑動一會兒。見圖:


2種方法日志比較

代碼如下:


日志代碼

009


iphone5 iOS7上UIScrollView的contentSize不能設置為CGFLOAT_MAX

最近在做閱讀的上下滑動翻頁功能,自然想到了UIScrollView
為了能無限翻頁,把UIScrollView.contentSize = CGSizeMake(width, CGFLOAT_MAX)
測試發現在iphone5 iOS7崩潰


崩潰截圖

解決方法:
UIScrollView.contentSize = CGSizeMake(width, 2^31);
可能原因是iphone5 iOS7是32位,不能大于2^32

008


JSQMessages的問題在iOS11上崩潰的問題

JSQMessagesComposerTextView(@interface JSQMessagesComposerTextView : UITextView)有個屬性:
@property (weak, nonatomic, nullable) id<JSQMessagesComposerTextViewPasteDelegate> pasteDelegate;

在iOS11上崩潰,原因:

@protocol UITextPasteConfigurationSupporting <UIPasteConfigurationSupporting>
@property (nonatomic, weak, nullable) id<UITextPasteDelegate> pasteDelegate;
@end

@interface UITextView () <UITextPasteConfigurationSupporting>
@end

UITextView實現了UITextPasteConfigurationSupporting協議,而UITextPasteConfigurationSupporting定義了pasteDelegate,JSQMessagesComposerTextView定義的pasteDelegate與系統的沖突了

解決方法:
修改JSQMessagesComposerTextView的pasteDelegate為jsq_pasteDelegate

007

NSKeyedUnarchiver在iOS8下讀取plist的問題

v7.3.0前用:
[NSArray writeToFile:savedFileName atomically:YES]來保存搜索記錄;是一個plist文件
v7.3.1后用:
[NSKeyedArchiver archiveRootObject:array toFile:savedFileName]來保存搜索記錄;是一個二進制文件

savedFileName都是同一個文件,在v7.3.1上覆寫了v7.3.0的plist文件為二進制文件

在iOS8.4下的系統用如下代碼讀取文件時,崩潰;但iOS10以上正常

    NSMutableArray *recordArray;
    recordArray = [NSKeyedUnarchiver unarchiveObjectWithFile:savedFileName];
    if (recordArray == nil) {
        //舊數據提取
        recordArray = [NSMutableArray arrayWithContentsOfFile:savedFileName];
    }

為了讓全部iOS版本都正常,修改代碼如下:

    NSMutableArray *recordArray;
    @try {
        recordArray = [NSKeyedUnarchiver unarchiveObjectWithFile:savedFileName];
        if (recordArray == nil) {
            //舊數據提取
            recordArray = [NSMutableArray arrayWithContentsOfFile:savedFileName];
        }
    }
    @catch (NSException* e) {
        recordArray = [NSMutableArray arrayWithContentsOfFile:savedFileName];
    }

006


狀態欄樣式引起的神樣問題

問題描述:

  1. UINavigationController里的2個ViewController:XXPlayerViewController, XXDownloaderManagerViewController.
  2. XXPlayerViewController不顯示NavigationBar,preferredStatusBarStyle方法返回UIStatusBarStyleLightContent
  3. XXDownloaderManagerViewController顯示NavigationBar,沒有重寫preferredStatusBarStyle方法,默認返回UIStatusBarStyleDefault
ViewController NavigationBar preferredStatusBarStyle
XXPlayer Hide UIStatusBarStyleLightContent
XXDownloaderManager Show UIStatusBarStyleDefault

步驟:XXDownloaderManagerViewController側滑顯示XXPlayerViewController,側滑取消,并馬上點擊NavigationBar的“返回”按鍵

問題:XXPlayerViewController顯示了XXDownloaderManagerViewController的UINavigationItem

解決方法:自定義的UINavigationController實現如下方法

- (UIViewController *)childViewControllerForStatusBarStyle {
    return self.topViewController;
}

參考:Bug when swiping from view with uinavigationbar to one without

005


AVAudioSessionRouteChangeNotification一般不在主線程通知

AVAudioSessionRouteChangeNotification一般不在主線程通知,需要注意多線程問題

004


iOS7上的問題02

speedSlider已創建,并在視圖層次中,創建時minimumTrackTintColor,maximumTrackTintColor不為代碼中的顏色,這時候調整值(比如應用設置成夜間模式),在iOS7上不生效

    //UISlider *speedSlider
    self.speedSlider.minimumTrackTintColor = RGB_COLOR(200, 100, 100);
    self.speedSlider.maximumTrackTintColor = RGB_COLOR(195, 206, 217);

iOS7上的問題01

有這么個函數:

- (void)showMainViewController:(NSInteger)pageIndex
{
}

它有一個參數:(NSInteger)pageIndex,在iOS7上,如下調用會有問題:

//targetVC實現了showMainViewController:方法
[targetVC performSelector:@selector(showMainViewController:) withObject:@0];
//或
[targetVC performSelector:@selector(showMainViewController:) withObject:[NSNumber numberWithInteger:0]];    

問題:pageIndex的值不為0,更像一個內存地址
解決方法:

((void(*)(id, SEL, NSInteger))objc_msgSend)(targetVC, @selector(showMainViewController:), 0);

003


Locale改變 NSCurrentLocaleDidChangeNotification

  • 通用-日期與時間-24小時制,收到通知
  • 通用-日期與時間-時區,不會收到通知
  • 通用-語言與地區-日歷,不會收到通知
  • 通用-語言與地區-地區,殺死應用程序
  • 通用-語言與地區-iPhone語言,殺死應用程序
  • 通用-語言與地區-溫度單位,收到通知

002


讓特定UICollectionViewCell滾到可見范圍內

問題:調用UICollectionView scrollToItemAtIndexPath: atScrollPosition: animated:不能讓Cell滾到可見范圍內
方法:可以這么調用:

[UICollectionView performBatchUpdates:^{
    [UICollectionView scrollToItemAtIndexPath: atScrollPosition: animated:];
} completion:nil];

001


不要在applicationDidEnterBackground做長時間操作

1. 按Home鍵進入后臺
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    sleep(10);//模擬長時間操作
}
2. 1秒后點擊應用進入前臺,應用能顯示
3. 這時點擊界面是沒有響應的
4. 10秒后applicationWillEnterForeground,applicationDidBecomeActive才被調用

NSLiteralSearch
區分 同一個字符(如日文的片假字)的半角與全角狀態[半角狀態 > 全角狀態]

NSWidthInsensitiveSearch
不區分 同一個字符(如日文的片假字)的半角與全角狀態[半角狀態 = 全角狀態]
同時指定兩個時,NSWidthInsensitiveSearch 比 NSLiteralSearch 的優先級高,綜合起來的結果: [半角狀態 = 全角狀態]

NSForcedOrderingSearch
NSForcedOrderingSearch 的優先級最高

000


NSString enumerateSubstringsInRange: options: usingBlock:可以斷句

應用場景:咪咕閱讀,掌閱等朗讀時分句子高亮

[string enumerateSubstringsInRange:NSMakeRange(0, string.length)
                           options:NSStringEnumerationBySentences | NSStringEnumerationLocalized
                        usingBlock:block];

比如:完整的內容為:


或格式化顯示:


格式化內容

斷句后的結果:


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375