調整你的網絡代碼
iOS中的網絡棧包含幾個用于與iOS設備的無線電硬件通信的接口。主要的編程接口是CFNetwork框架,它構建與Core Foundation框架的BSD套接字和不透明類型之上,用于與網絡實體進行通信。你也可以使用Foundation框架中的NSStream類以及系統的Core OS層中的低級BSD套接字。
關于如何使用CFNetwork框架來進行網絡連接的信息,參加CFNetwork Programming Guide 和 CFNetwork Framework Reference。關于使用NSStream類的信息,參見Foundation Framework Reference。
實現高效網絡的技巧
實現用于通過網絡接收或傳輸數據的代碼,是設備上耗能最大的操作之一。把傳輸和接收數據的時間最小化可以幫助提高電池壽命。為此,你應該在編寫網絡相關的代碼的時候考慮下面的技巧:
- 對于你控制的協議,在定義數據格式時盡可能的緊湊。
- 避免使用聊天(chatty)協議。
- 盡可能的一次傳輸較多的數據包。
蜂窩網絡和Wi-Fi無線電被設計為非活動時關閉電源。這個動作,會消耗幾秒鐘。如果應用每隔幾秒鐘傳輸一個小數據,無線電或許會保持在這個狀態且持續消耗電量,即使是不做任何操作的時候也是如此。所以與其經常性傳輸小數據,還不如一次傳輸一個較大的數據,兩次傳輸之間的間隔大一些。
當與網絡進行通信的時候,數據包可能隨時丟失。所以,當編寫網絡代碼的時候,你應妥善處理錯誤使代碼強壯。實現對網絡條件改變的響應是非常明智的,但是,如果這些處理沒有始終如一的調用也不要意外。例如,Bonjour網絡就不是當網絡服務消失時馬上會被回調。Bonjour系統服務會在它收到服務消失的通知的時候,里脊調用瀏覽回調。但是網絡服務消失的時候不會有通知。如果設備提供網絡服務意外失去網絡連接,或者傳輸中通知丟失的時候,這種情況就可能發生。
使用Wi-Fi
如果應用使用Wi-Fi訪問網絡,你必須通過在應用的 Info.plist文件中包含UIRequiresPersistentWiFi 鍵,來通知系統。包含此鍵可以讓系統指導它應該在檢測到Wi-Fi熱點的時候顯示網絡選擇對話框。它也讓系統知道,當應用運行的時候,不要嘗試關閉Wi-Fi硬件。
為了防止Wi-Fi硬件消耗太多電量,iOS又一個內建的定時器,如果30分鐘內沒有應用通過UIRequiresPersistentWiFi鍵請求使用Wi-Fi,那么就會完全關閉Wi-Fi硬件,如果用戶啟動一個包含此鍵的應用,iOS會在應用生命周期內有效的禁用該定時器。但是,一旦應用退出或者進入掛起狀態,系統就會重啟這個定時器。
注意:注意,即使當UIRequiresPersistentWiFi的值是true,只要設備處于空閑(也就是,鎖屏)時它也不起作用。該應用被認為無效,雖然它其他功能可能還有效,但是它不會有Wi-Fi連接。
更多 UIRequiresPersistentWiFi 鍵以及Info.plist文件的鍵的信息,參見The Information Property List File。
飛行模式警告
如果應用在設備處于飛行模式的時候啟動,系統可能會顯示一個警告,通知用戶設備現處的狀態。只有當符合以下所有條件的時候,系統才會顯示這個警告:
- 應用的Info.plist文件包含UIRequiresPersistentWiFi鍵,并設該鍵的值為true。
- 應用在設備處于飛行模式的時候啟動。
- 設備上的Wi-Fi在切換到飛行模式之后還沒有重新手動啟用。
改善你的文件管理
最小化你寫入磁盤的數據量。文件操作相當慢,并且涉及寫入閃存,它是有壽命限制的。下面是一些可以幫助你最小化文件操作的技巧:
- 僅寫入文件更改的部分,并可以對更改進行合并。避免寫入整個文件只是為了更改少數字節。
- 當定義文件格式的時候,經常性的將修改的內容組織在一起,以便最小化每次需要寫入磁盤的數據量。
- 如果數據是由隨機訪問的結構化內容組層,把它存儲在Core Data或者SQLite數據庫,特別是當你操作的數據會不斷成長的時候。
避免把緩存文件寫入磁盤。此規則的唯一例外是,當應用退出以及需要寫入狀態信息的時候,這些內容會在應用下次啟動的時候將應用恢復到之前的狀態。
使用程序備份更有效率
備份可以通過iCloud或者當用戶使用iTunes同步設備的時候發生。通過備份,文件將從設備傳輸到用戶的電腦或者是iCloud賬戶。在應用沙盒中的文件位置決定了這些文件能否備份以及恢復。如果你的應用創建了很多頻繁更改的大型文件,并將其放在備份的位置,備份的過程將非常緩慢。就像你寫文件管理代碼一樣,你需要注意這個情況。
應用備份最佳實踐
應用無需為備份或恢復做準備。帶有激活的iCloud賬戶的設備,會在合適的時候把數據備份到iCloud。對于插入計算機的設備,iTunes會對應用的數據文件執行一個增量備份。但是iCloud和iTunes不會備份下列目錄里的內容。
- <Application_Home>/AppName.app
- <Application_Data>/Library/Caches
- <Application_Data>/tmp
為了防止同步過程花費太長時間,選擇應用的主目錄放置文件。存儲大型文件的應用的備份過程會非常慢。這些應用也消耗大量用戶的可用存儲空間,這可能會導致用戶刪除該應用,或者禁止應用備份到iCloud。考慮到這一點,你應該根據下面的準則來存儲應用數據:
- 至關重要的數據應該存儲在<Application_Data>/Documents目錄。至關重要的數據是那些不能夠通過應用創建的數據,例如用戶文件,以及其他用戶生成的內容。
- 支持文件包括應用下載或生成的文件,以及應用能在需要時創建的文件。存儲應用的支持文件的位置依賴于當前iOS的版本。
- 在iOS5.1及更高版本,支持文件保存在<Application_Data>/Library/Application Support目錄,并且使用setResourceValue:forKey:error:方法添加NSURLIsExcludedFromBackupKey屬性到相應的NSURL對象。(如果你使用Core Foundation,使用CFURLSetResourcePropertyForKey函數將kCFURLIsExcludedFromBackupKey鍵添加到你的 CFURLRef對象。)申請這些屬性,防止文件被備份到iTunes或iCloud。如果你有很多支持文件,你應該把它們存儲在自定義的子目錄中,并為適應目錄而申請擴展屬性。
- 在iOS5.0及更早版本,在<Application_Data>/Library/Caches 目錄保存支持支持文件,來防止備份。如果目標是iOS5.0.1,參見How do I prevent files from being backed up to iCloud and iTunes?獲取關于從備份中排除文件的信息。
- 緩存數據應該保存在<Application_Data>/Library/Caches目錄。你應該放在Caches目錄里的文件包括(但不限于)數據庫緩存文件以及可下載內容,例如雜志、報紙、地圖應用使用的文件。應用應該能夠優雅的處理緩存數據被系統刪除以便釋放磁盤空間的情況。
- 臨時數據應該被保存在<Application_Data>/tmp目錄。臨時數據包括任何你不需要長時間持有的數據。當你使用完的它們的時候要記得刪除,以便它們不浪費用戶設備的空間。
雖然iTunes備份應用束本身,但它不會在每次同步操作的時候都這樣做。直接從設備購買的應用會在設備下次和iTunes同步的時候備份。除非應用束有改變(例如應用有更新),否則應用不會在同步操作期間進行備份。
關于如何使用應用中的目錄的更多指導,參見File System Programming Guide。
在應用更新期間保存文件
當用戶下載應用的更新的時候,iTunes在一個新的應用目錄里安裝更新。然后把用戶的數據文件從舊安裝位置移動到新的安裝位置。然后再刪除舊的安裝內容。在以下目錄中的文件會在更新期間會得到保護。
- <Application_Data>/Documents
- <Application_Data>/Library
盡管在其他用戶目錄中的文件也可以被移動,但你不應該在更新后依然依靠它們存在。
將工作移出主線程
確保限制可以在應用主線程上進行工作類型。主線程是應用處理觸摸事件和其他用戶輸入的地方。想要確保應用總是對用戶有響應,你就永遠不要在主線程上執行長時運行或無時限任務,例如訪問網絡的任務。相反,你應該把這些任務移動到后臺線程。首選的方式是使用Grand Central Dispatch(GCD)或者NSOperation對象來異步執行任務。
把這些任務移動到后臺,可以讓你的主線程可以繼續處理用戶輸入,這對應用的啟動或退出尤其重要。在這些時候,應用被希望能夠及時響應事件。如果應用的主線程在且哦哪個的時候被阻止,系統會在啟動完成之前殺死應用。若果主線程在退出的時候被阻止,系統會在應用又機會寫出關鍵用戶數據之前殺死應用。
更多關于使用GCD、操作對象、以及線程的信息,參見Concurrency Programming Guide。