1. 程式人生 > >[ios-必看] WWDC 2013 Session筆記

[ios-必看] WWDC 2013 Session筆記

iOS7的後臺多工特性iOS7的後臺多工特性

這是我的WWDC2013系列筆記中的一篇,完整的筆記列表請參看這篇總覽。本文僅作為個人記錄使用,也歡迎在許可協議範圍內轉載或使用,但是還煩請保留原文連結,謝謝您的理解合作。如果您覺得本站對您能有幫助,您可以使用RSS郵件方式訂閱本站,這樣您將能在第一時間獲取本站資訊。

本文涉及到的WWDC2013 Session有

  • Session 204 What’s New with Multitasking
  • Session 705 What’s New in Foundation Networking

iOS7以前的Multitasking

iOS的多工是在iOS4的時候被引入的,在此之前iOS的app都是按下Home鍵就被幹掉了。iOS4雖然引入了後臺和多工,但是實際上是 偽多工,一般的app後臺並不能執行自己的程式碼,只有少數幾類服務在通過註冊後可以真正在後臺執行,並且在提交到AppStore的時候也會被嚴格稽核 是否有越權行為,這種限制主要是出於對於裝置的續航和安全兩方面進行的考慮。之後經過iOS5和6的逐漸發展,後臺能執行的服務的種類雖然出現了增加,但 是iOS後臺的本質並沒有變化。在iOS7之前,系統所接受的應用多工可以大致分為幾種:

  • 後臺完成某些花費時間的特定任務
  • 後臺播放音樂等
  • 位置服務
  • IP電話(VoIP)
  • Newsstand

在WWDC 2013的keynote上,iOS7的後臺多工改進被專門拿出來向開發者進行了介紹,到底iOS7裡多工方面有什麼新的特性可以利用,如何使用呢? 簡單來說,iOS7在後臺特性方面有很大改進,不僅改變了以往的一些後臺任務處理方式,還加入了全新的後臺模式,本文將針對iOS7中新的後臺特性進行一 些學習和記錄。大體來說,iOS7後臺的變化在於以下四點:

  • 改變了後臺任務的執行方式
  • 增加了後臺獲取(Background Fetch)
  • 增加了推送喚醒(靜默推送,Silent Remote Notifications)
  • 增加了後臺傳輸(Background Transfer Service)

iOS7的多工

後臺任務

首先看看後臺任務的變化,先說這方面的改變,而不是直接介紹新的API,是因為這個改變很典型地代表了iOS7在後臺任務管理和能耗控制上的大體思路。從上古時期開始(其實也就4.0),UIApplication提供了-beginBackgroundTaskWithExpirationHandler:方 法來使app在被切到後臺後仍然能保持執行一段時間,app可以用這個方法來確保一些很重很慢的工作可以在急不可耐的使用者將你的應用扔到後臺後還能完成, 比如編碼視訊,上傳下載某些重要檔案或者是完成某些資料庫操作等,雖然時間不長,但在大多數情況下勉強夠用。如果你之前沒有使用過這個API的話,它使用 起來大概是長這個樣子的:

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
- (void) doUpdate
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self beginBackgroundUpdateTask];
        NSURLResponse * response = nil;
        NSError  * error = nil;
        NSData * responseData = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error];
        // Do something with the result
        [self endBackgroundUpdateTask];
    });
}
- (void) beginBackgroundUpdateTask
{
    self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [self endBackgroundUpdateTask];
    }];
}
- (void) endBackgroundUpdateTask
{
    [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
    self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}  

beginBackgroundTaskWithExpirationHandler:裡寫一個超時處理(系統只給app分配了一定時間來進行後臺任務,超時之前會呼叫這個block),然後進行開始進行後臺任務處理,在任務結束或者過期的時候call一下endBackgroundTask:使之與begin方法配對(否則你的app在後臺任務超時的時候會被殺掉)。同時,你可以使用UIApplication例項的backgroundTimeRemaining屬性來獲取剩餘的後臺執行時間。

具體的執行時間來說,在iOS6和之前的系統中,系統在使用者退出應用後,如果應用正在執行後臺任務的話,系統會保持活躍狀態直到後臺任務完成或者是超時以後,才會進入真正的低功耗休眠狀態。

iOS6之前的後臺任務處理iOS6之前的後臺任務處理

而在iOS7中,後臺任務的處理方式發生了改變。系統將在使用者鎖屏後儘快讓裝置進入休眠狀態,以節省電力,這時後臺任務是被暫停的。之後在裝置在特 定時間進行系統應用的操作被喚醒(比如檢查郵件或者接到來電等)時,之前暫停的後臺任務將一起進行。就是說,系統不會專門為第三方的應用保持裝置處於活動 狀態。如下圖示

iOS7的後臺任務處理iOS7的後臺任務處理

這個變化在不減少應用的後臺任務時間長度的情況下,給裝置帶來了更多的休眠時間,從而延長了續航。對於開發者來說,這個改變更多的是系統層級的變 化,對於非網路傳輸的任務來說,保持原來的用法即可,新系統將會按照新的喚醒方式進行處理;而對於原來在後臺做網路傳輸的應用來說,蘋果建議在iOS7中 使用NSURLSession,建立後臺的session並進行網路傳輸,這樣可以很容易地利用更好的後臺傳輸API,而不必受限於原來的時長,關於這個具體的我們一會兒再說。

後臺獲取(Background Fetch)

現在的應用無法在後臺獲取資訊,比如社交類應用,使用者一定需要在開啟應用之後才能進行網路連線,獲取新的訊息條目,然後才能將新內容呈現給使用者。說 實話這個體驗並不是很好,使用者在開啟應用後必定會有一段時間的等待,每次皆是如此。iOS7中新加入的後臺獲取就是用來解決這個不足的:後臺獲取乾的事情 就是在使用者開啟應用之前就使app有機會執行程式碼來獲取資料,重新整理UI。這樣在使用者開啟應用的時候,最新的內容將已然呈現在使用者眼前,而省去了所有的載入 過程。想想看,沒有載入的網路體驗的世界,會是怎樣一種感覺。這已經不是smooth,而是真的amazing了。

那具體應該怎麼做呢?一步一步來:

啟用後臺獲取

首先是修改應用的Info.plist,在UIBackgroundModes中加入fetch,即可告訴系統應用需要後臺獲取的許可權。另外一種更簡單的方式,得益於Xcode5的Capabilities特性(參見可以參見我之前的一篇WWDC2013筆記 Xcode5和ObjC新特性),現在甚至都不需要去手動修改Info.plist來進行添加了,開啟Capabilities頁面下的Background Modes選項,並勾選Background fetch選項即可(如下圖)。

在Capabilities中開啟Background Modes在Capabilities中開啟Background Modes

筆者寫這篇文章的時候iOS7還沒有上市,也沒有相關的稽核資料,所以不知道如果只是在這裡打開了fetch選項,但卻沒有實現的話,應用會不會無 法通過稽核。但是依照蘋果一貫的做法來看,如果聲明瞭需要某項後臺許可權,但是結果卻沒有相關實現的話,被拒掉的可能性還是比較大的。因此大家儘量不要拿上 線產品進行實驗,而應當是在demo專案裡研究明白以後再到上線產品中進行實裝。

設定獲取間隔

對應用的UIApplication例項設定獲取間隔,一般在應用啟動的時候呼叫以下程式碼即可:

1
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];

如果不對最小後臺獲取間隔進行設定的話,系統將使用預設值UIApplicationBackgroundFetchIntervalNever,也就是永遠不進行後臺獲取。當然,-setMinimumBackgroundFetchInterval:方 法接受的是NSTimeInterval,因此你也可以手動指定一個以秒為單位的最小獲取間隔。需要注意的是,我們都已經知道iOS是一個非常霸道為我獨 尊的系統,因此自然也不可能讓一介區區第三方應用來控制系統行為。這裡所指定的時間間隔只是代表了“在上一次獲取或者關閉應用之後,在這一段時間內一定不 會去做後臺獲取”,而真正具體到什麼時候會進行後臺獲取,那完全是要看系統孃的心情的我們是無從得知的。系統將根據你的設定,選擇 比如接收郵件的時候順便為你的應用獲取一下,或者也有可能專門為你的應用喚醒一下裝置。作為開發者,我們應該做的是為使用者的電池考慮,儘可能地選擇合適自 己應用的後臺獲取間隔。設定為UIApplicationBackgroundFetchIntervalMinimum的話,系統會盡可能多儘可能快地 為你的應用進行後臺獲取,但是比如對於一個天氣應用,可能對實時的資料並不會那麼關心,就完全不必設定為 UIApplicationBackgroundFetchIntervalMinimum,也許1小時會是一個更好的選擇。新的Mac OSX 10.9上已經出現了功耗監測,用於讓使用者確定什麼應用是能耗大戶,有理由相信同樣的東西也可能出現在iOS上。如果不想讓使用者因為你的應用是耗電大戶而 怒刪的話,從現在開始注意一下應用的能耗還是蠻有必要的(做綠色環保低碳的iOS app,從今天開始~)。

實現後臺獲取程式碼並通知系統

在完成了前兩步後,只需要在AppDelegate裡實現-application:performFetchWithCompletionHandler:就 行了。系統將會在執行fetch的時候呼叫這個方法,然後開發者需要做的是在這個方法裡完成獲取的工作,然後重新整理UI,並通知系統獲取結束,以便系統儘快 回到休眠狀態。獲取資料這是應用相關的內容,在此不做贅述,應用在前臺能完成的工作在這裡都能做,唯一的限制是系統不會給你很長時間來做fetch,一般 會小於一分鐘,而且fetch在絕大多數情況下將和別的應用共用網路連線。這些時間對於fetch一些簡單資料來說是足夠的了,比如微博的新條目(大圖除 外),接下來一小時的天氣情況等。如果涉及到較大檔案的傳輸的話,用後臺獲取的API就不合適了,而應該使用另一個新的檔案傳輸的API,我們稍後再說。 類似前面提到的後臺任務完成時必須通知系統一樣,在在獲取完成後,也必須通知系統獲取完成,方法是呼叫-application:performFetchWithCompletionHandler:的handler。這個CompletionHandler接收一個UIBackgroundFetchResult作為引數,可供選擇的結果有UIBackgroundFetchResultNewData,UIBackgroundFetchResultNoData,UIBackgroundFetchResultFailed三種,分別表示獲取到了新資料(此時系統將對現在的UI狀態截圖並更新App Switcher中你的應用的截圖),沒有新資料,以及獲取失敗。寫一個簡單的例子吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//File: YourAppDelegate.m
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    UINavigationController *navigationController = (UINavigationController*)self.window.rootViewController;
    id fetchViewController = navigationController.topViewController;
    if ([fetchViewController respondsToSelector:@selector(fetchDataResult:)]) {
        [fetchViewController fetchDataResult:^(NSError *error, NSArray *results){
            if (!error) {
              if (results.count != 0) {
                  //Update UI with results.
                  //Tell system all done.
                  completionHandler(UIBackgroundFetchResultNewData);
              } else {
                  completionHandler(UIBackgroundFetchResultNoData);
              }
            } else {
                completionHandler(UIBackgroundFetchResultFailed);
            }
        }];
    } else {
        completionHandler(UIBackgroundFetchResultFailed);
    }
}

當然,實際情況中會比這要複雜得多,使用者當前的ViewController是否合適做獲取,獲取後的資料如何處理都需要考慮。另外要說明的是上面 的程式碼在獲取成功後直接在appDelegate裡更新UI,這只是為了能在同一處進行說明,但卻是不正確的結構。比較好的做法是將獲取和更新UI的業務 邏輯都放到fetchViewController裡,然後向其傳送獲取訊息的時候將completionHandler作為引數傳入,並在 fetchViewController裡完成獲取結束的報告。

另一個比較神奇的地方是系統將追蹤使用者的使用習慣,並根據對每個應用的使用時刻給一個合理的fetch時間。比如系統將記錄你在每天早上9點上班的 電車上,中午12點半吃飯時,以及22點睡覺前會刷一下微博,只要這個習慣持續個三四天,系統便會將應用的後臺獲取時刻調節為9點,12點和22點前一 點。這樣在每次你開啟應用都直接有最新內容的同時,也節省了電量和流量。

後臺獲取的除錯

既然是系統決定的fetch,那我們要如何測試寫的程式碼呢?難道是將應用退到後臺,然後安心等待系統進行後臺獲取麼?當然不是…Xcode5為我們提供了兩種方法來測試後臺獲取的程式碼。一種是從後臺獲取中啟動應用,另一種是當應用在後臺時模擬一次後臺推送。

對於前者,我們可以新建一個Scheme來專門除錯從後臺啟動。點選Xcode5的Product->Scheme->Edit Scheme(或者直接使用快捷鍵⌘<)。 在編輯Scheme的視窗中點Duplicate Scheme按鈕複製一個當前方案,然後在新Scheme的option中將Background Fetch打上勾。從這個Scheme來執行應用的時候,應用將不會直接啟動切入前臺,而是呼叫後臺獲取部分程式碼並更新UI,這樣再點選圖示進入應用時, 你應該可以看到最新的資料和更新好的UI了。

更改Scheme的選項為從後臺獲取事件中啟動更改Scheme的選項為從後臺獲取事件中啟動

另一種是當應用在後臺時,模擬一次後臺獲取。這個比較簡單,在app除錯執行時,點選Xcode5的Debug選單中的Simulate Background Fetch,即可模擬完成一次獲取呼叫。

推送喚醒(Remote Notifications)

遠端推送(Remote Push Notifications)可以說是增加使用者留存率的不二法則,在iOS6和之前,推送的型別是很單一的,無非就是顯示標題內容,指定聲音等。使用者通過 解鎖進入你的應用後,appDelegate中通過推送開啟應用的回撥將被呼叫,然後你再獲取資料,進行顯示。這和沒有後臺獲取時的開啟應用後再獲取資料 重新整理的問題是一樣的。在iOS7中這個行為發生了一些改變,我們有機會使裝置在接收到遠端推送後讓系統喚醒裝置和我們的後臺應用,並先執行一段程式碼來準備 資料和UI,然後再提示使用者有推送。這時使用者如果解鎖裝置進入應用後將不會再有任何載入過程,新的內容將直接得到呈現。

實裝的方法和剛才的後臺獲取比較類似,還是一步步來:

啟用推送喚醒

和上面的後臺獲取類似,更改Info.plist,在UIBackgroundModes下加入remote-notification即可開啟,當然同樣的更簡單直接的辦法是使用Capabilities。

更改推送的payload

在iOS7中,如果想要使用推送來喚醒應用執行程式碼的話,需要在payload中加入content-available,並設定為1。

1
2
3
4
aps {
     content-available: 1
     alert: {...}
   }



實現推送喚醒程式碼並通知系統

最後在appDelegate中實現-application:didReceiveRemoteNotification:fetchCompletionHandle:。這部分內容和上面的後臺獲取部分完全一樣,在此不再重複。

一些限制和應用的例子

因為一旦推送成功,使用者的裝置將被喚醒,因此這類推送不可能不受到限制。Apple將限制此類推送的頻率,當頻率超過一定限制後,帶有 content-available標誌的推送將會被阻塞,以保證使用者裝置不被頻繁喚醒。按照Apple的說法,這個頻率在一小時內個位數次的推送的話不 會有太大問題。

Apple給出了幾個典型的應用情景,比如一個電視節目類的應用,當用戶標記某些劇目為喜愛時,當這些劇有更新時,可以給使用者傳送靜默的喚醒推送通 知,客戶端在接到通知後檢查更新並開始後臺下載(注意後臺下載的部分絕對不應該在推送回調中做,而是應該使用新的後臺傳輸服務,後面詳細介紹)。下載完成 後傳送一個本地推送告知使用者新的內容已經準備完畢。這樣在使用者注意到推送並開啟應用的時候,所有必要的內容已經下載完畢,UI也將切換至使用者喜愛的劇目, 使用者只需要點選播放即可開始真正使用應用,這絕對是無比順暢和優秀的體驗。另一種應用情景是檔案同步類,比如使用者標記了一些檔案為需要隨時同步,這樣使用者 在其他裝置或網頁服務上更改了這些檔案時,可以傳送靜默推送然後使用後臺傳輸來保持這些檔案隨時是最新。

如果您是一路看下來的話,不難發現其實後臺獲取和靜默推送在很多方面是很類似的,特別是實現和處理的方式,但是它們適用的情景是完全不同的。後臺獲 取更多地使用在泛資料模式下,也即使用者對特定資料並不是很關心,資料應該被更新的時間也不是很確定,典型的有社交類應用和天氣類應用;而靜默推送或者是推 送喚醒更多地應該是使用者感興趣的內容發生更新時被使用,比如訊息類應用和內容型服務等。根據不同的應用情景,選擇合適的後臺策略(或者混合使用兩者),以 帶給使用者絕佳體驗,這是Apple所期望iOS7開發者做到的。

後臺傳輸(Background Transfer Service)

iOS6和之前,iOS應用在大塊資料的下載這一塊限制是比較多的:只有應用在前臺時能保持下載(使用者按Home鍵切到後臺或者是等到裝置自動休眠 都可能中止下載),在後臺只有很短的最多十分鐘時間可以保持網路連線。如果想要完成一個較大資料的下載,使用者將不得不開啟你的app並且基本無所事事。很 多這種時候,使用者會想要是在下載的時候能切到別的應用刷刷微博或者玩玩遊戲,然後再切回來的就已經下載完成了的話,該有多好。iOS7中,這可以實現了。 iOS7引入了後臺傳輸的相關方式,用來保證應用退出後資料下載或者上傳能繼續進行。這種傳輸是由iOS系統進行管理的,沒有時間限制,也不要求應用執行 在前臺。

想要實現後臺傳輸,就必須使用iOS7的新的網路連線的類,NSURLSession。這是iOS7中引入用以替代陳舊的NSURLConnection的類,著名的AFNetworking甚至不惜從底層開始完全重寫以適配iOS7和NSURLSession(參見這裡),NSURLSession 的重要性可見一斑。在這裡我主要只介紹NSURLSession在後臺傳輸中的一些使用,關於這個類的其他用法和對原有NSURLConnection的 加強,只做稍微帶過而不展開,有興趣深入挖掘和使用的童鞋可以參看Apple的文件(或者更簡單的方式是使用AFNetworking來處理網路相關內 容,而不是直接和CFNetwork框架打交道)。

步驟和例子

後臺傳輸的的實現也十分簡單,簡單說分為三個步驟:建立後臺傳輸用的NSURLSession物件;向這個物件中加入對應的傳輸的NSURLSessionTask,並開始傳輸;在實現appDelegate裡實現-application:handleEventsForBackgroundURLSession:completionHandler:方法,以重新整理UI及通知系統傳輸結束。接下來結合程式碼來看一看實際的用法吧~

首先我們需要一個用於後臺下載的session:

1
2
3
4
5
6
7
8
9
10
11
- (NSURLSession *)backgroundSession
{
    //Use dispatch_once_t to create only one background session. If you want more than one session, do with different identifier
    static NSURLSession *session = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.yourcompany.appId.BackgroundSession"];
        session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
    });
    return session;
}

這裡建立並配置了NSURLSession,將其指定為後臺session並設定delegate。

接下來向其中加入對應的傳輸用的NSURLSessionTask,並啟動下載。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//@property (nonatomic) NSURLSession *session;
//@property (nonatomic) NSURLSessionDownloadTask *downloadTask;
- (NSURLSession *)backgroundSession
{
    //...
}
- (void) beginDownload
{
    NSURL *downloadURL = [NSURL URLWithString:DownloadURLString];
    NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL];
    self.session = [self backgroundSession];
    self.downloadTask = [self.session downloadTaskWithRequest:request];
    [self.downloadTask resume];
}

最後一步是在appDelegate中實現-application:handleEventsForBackgroundURLSession:completionHandler:

1
2
3
4
5
6
7
8
9
10
11
//AppDelegate.m
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier
  completionHandler:(void (^)())completionHandler
{
    //Check if all transfers are done, and update UI
    //Then tell system background transfer over, so it can take new snapshot to show in App Switcher
    completionHandler();
    //You can also pop up a local notification to remind the user
    //...
}

NSURLSession和對應的NSURLSessionTask有以下重要的delegate方法可以使用:

1
2
3
4
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                              didFinishDownloadingToURL:(NSURL *)location;
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                           didCompleteWithError:(NSError *)error;

一旦後臺傳輸的狀態發生變化(包括正常結束和失敗)的時候,應用將被喚醒並執行appDelegate中的回撥,接下來 NSURLSessionTask的委託方法將在後臺被呼叫。雖然上面的例子中直接在appDelegate中call了 completionHandler,但是實際上更好的選擇是在appDelegate中暫時持有completionHandler,然後在 NSURLSessionTask的delegate方法中檢查是否確實完成了傳輸並更新UI後,再呼叫completionHandler。另外,你的 應用到現在為止只是在後臺執行,想要提醒使用者傳輸完成的話,也許你還需要在這個時候傳送一個本地推送(記住在這個時候你的應用是可以執行程式碼的,雖然是在 後臺),這樣使用者可以注意到你的應用的變化並回到應用,並開始已經準備好資料和介面。

一些限制

首先,後臺傳輸只會通過wifi來進行,使用者大概也不會開心蜂窩資料的流量被後臺流量用掉。後臺下載的時間與以前的關閉應用後X分鐘的模式不一樣, 而是為了節省電力變為離散式的下載,並與其他後臺任務併發(比如接收郵件等)。另外還需要注意的是,對於下載後的內容不要忘記寫到應用的目錄下(一般來說 這種可以重複獲得的內容應該放到cache目錄下),否則如果由於應用完全退出的情況導致沒有儲存到可再次訪問的路徑的話,那可就白做工了。

後臺傳輸非常適合用於檔案,照片或者追加遊戲內容關卡等的下載,如果配合後臺獲取或者靜默推送的話,相信可以完全很多很有趣,並且以前被限制而無法實現的功能。

相關推薦

[ios-] WWDC 2013 Session筆記

iOS7的後臺多工特性 這是我的WWDC2013系列筆記中的一篇,完整的筆記列表請參看這篇總覽。本文僅作為個人記錄使用,也歡迎在許可協議範圍內轉載或使用,但是還煩請保留原文連結,謝謝您的理解合作。如果您覺得本站對您能有幫助,您可以使用RSS或郵件方式訂閱本站,這樣您將能在第一時間獲取本站資訊。 本文涉及到的

WWDC 2012 Session筆記——202, 228, 232 AutoLayout(自動佈局)入門

Tagged iOS, objective-c, WWDC, Xcode, 開發 這是博主的WWDC2012筆記系列中的一篇,完整的筆記列表可以參看這裡。如果您是首次來到本站,也許您會有興趣通過RSS,或者通過頁面下方的郵件訂閱的方式訂閱本站。 AutoLayout

WWDC 2012 Session筆記——219 Advanced Collection Views and Building Custom Layouts

這是博主的WWDC2012筆記系列中的一篇,完整的筆記列表可以參看這裡。如果您是首次來到本站,也許您會有興趣通過RSS,或者通過頁面左側的郵件訂閱的方式訂閱本站。 在上一篇UICollectionView的入門介紹中,大概地對iOS6新加入的強大的UICollectio

【讀書筆記iOS-查一個軟件ipa包的內容

技術 -s alt dsm clas rda 軟件 選中 tun 一,打開itunes----->我的iPhone應用程序。 二,右鍵點擊app---->在Finder中顯示---->出現下圖所看到的界面。

Python的總結筆記

1.在Python中,一般來說一條語句佔用一行。一條語句結束一般不需要使用C語言中的“;”,但在Python中也可以使用“;”將兩條語句寫在一行。另外,如果縮排語句中只有一條語句,也可以將其寫在“:”之後。   2.單引號中的字串可以包含雙引號,雙引號中的字串可以包含單引號,而不需

iOS開發 iOS10推送(基礎篇)

轉自: http://www.jianshu.com/p/f5337e8f336d iOS開發 iOS10推送必看(基礎篇) 字數1380  閱讀2685  評論52  喜歡80 iOS10更新之

iOS中Runtime的幾種基本用法記錄(

Runtime顧名思義執行時,就是系統在執行的時候的一些機制,最主要的是訊息機制。下面這篇文章主要給大家介紹了關於iOS中Runtime的幾種基本用法,文中通過示例程式碼介紹的非常詳細,需要的朋友下面隨著小編來一起學習學習吧 Runtime 介紹 這不是一遍介紹關於Runtime實現

iOS精選書籍

今天興致一來稍稍整理了一下部分iOS的書籍,絕對的乾貨! 部分書籍 《Object-C程式設計之道》 連結:https://pan.baidu.com/s/1rbJQXmIA_QFm-5cXw9hV5g 提取碼:nvlz 《iOS開發進階》 連結:https

java程式設計思想重點筆記(java程式設計師

Java中的多型性理解(注意與C++區分) Java中除了static方法和final方法(private方法本質上屬於final方法,因為不能被子類訪問)之外,其它所有的方法都是動態繫結,這意味著通常情況下,我們不必判定是否應該進行動態繫結—它會自動發生。 fin

蘋果IOS系統內購退款,4年資深老玩家的慘痛教訓,!!

IOS蘋果退款失敗了還能退嗎?這個的話我是不敢保證的,一個賬號有很多因素會影響成功率.我也不能保證百分之百能給大家挽回損失.不過我會盡全力去幫助大家.不過就算id被拉黑沒有退款資格,也不用擔心.我這裡會為大家講講如何去養好一個ID 蘋果系統針對蘋果使用者的一項政

新手,史上最全的iOS開發教程集錦,沒有之一!

最近大火的iPhone XS Max和iPhone XS,不知道有沒有同學已經下手了呢?一萬三的價位確實讓很多人望而卻步啊。據說為了贏得中國的使用者,專門出了雙卡雙待的,可想而知中國市場這塊“肥肉”人人都想要。 近幾年,無論蘋果出什麼樣的產品以及多高的價位,都會有非常多的蘋

iOS開發 iOS10推送

iOS10更新之後,推送也是做了一些小小的修改,下面我就給大家仔細說說。希望看完我的這篇文章,對大家有所幫助。 一、簡單入門篇---看完就可以簡單適配完了 相對簡單的推送證書以及環境的問題,我就不在這裡講啦,我在這裡說的,是指原有工程的適配。 1.首先我們需

iOS - 基礎知識總結(OC版) 面試 再不就要用swift了[轉]

轉自:https://www.cnblogs.com/baitongtong/p/5869004.html OC的理解與特性 OC作為一門面向物件的語言,自然具有面向物件的語言特性:封裝、繼承、多型。它既具有靜態語言的特性(如C++),又有動態語言的效率(動態繫結、動態載入等)。總體

Java程式設計思想重點筆記(Java開發

Java程式設計思想,Java學習必讀經典,不管是初學者還是大牛都值得一讀,這裡總結書中的重點知識,這些知識不僅經常出現在各大知名公司的筆試面試過程中,而且在大型專案開發中也是常用的知識,既有簡單的概念理解題(比如is-a關係和has-a關係的區別),也有深入的涉及RTTI和JVM底層反編譯知識。

系列】iOS程式設計思想集大成者

RAC是ReactiveCocoa家族一員。這是一個響應式家族,在我看來RAC完全配得上:“程式設計思想之集大成者” 這個稱號!在內部封裝的函式式、面向物件、響應式、封裝很多關於iOS原生,最大限度便利的開發者使用! 很多部落格都說RAC好用,但發現很少有如何學習RAC的文章。不知道該從

Java程式設計思想重點筆記(Java開發)

1. Java中的多型性理解(注意與C++區分) Java中除了static方法和final方法(private方法本質上屬於final方法,因為不能被子類訪問)之外,其它所有的方法都是動態繫結,這意味著通常情況下,我們不必判定是否應該進行動態繫結—它會自動發生。 fi

演算法比賽前懂的演算法基礎知識 筆記總結(Java)

1、避免溢位,要記住各個資料型別的大小:(1)byte:-128~127,1個位元組(2)short:-32763~32767,2個位元組(3)int:-21億多~21億多,4個位元組,(快速記憶:2開頭,10位數)(4)long:(快速記憶:9開頭,19位數)(5)floa

iOS面試,最全梳理(二)

HTTP協議的特點,關於HTTP請求GET和POST的區別 GET和POST的區別: HTTP超文字傳輸協議,是短連線,是客戶端主動傳送請求,伺服器做出響應,伺服器響應之後,連結斷開。HTTP是一個屬於應用層面向物件的協議,HTTP有兩類報文:請求報文和響應報文。 HTTP請求報文:一個

移動開發入門——iOS 開發入門書籍推薦

整理了一些iOS 開發入門級別的書籍推薦給大家,每本都是很經典的著作,對於初學者來說是很值得一看的學習資料,希望能幫到大家! 本書將帶你走上建立iOS應用程式的大道。 我們的目標是讓你通過初步學習,理解iOS應用程式的執行和構建方式。在學習過程中,你將建

新手!Office Web Apps 2013 安裝與配置(實戰)

har 集成 令行 ice note 3.3 新建 author mil 分享人:廣州華軟 星塵 一. 前言 Office Web Apps Server 是Office 服務器產品,它可提供在Sharepoint 2013網站中在線瀏覽和編輯 Word、Power