Writing Energy Efficient Apps


#What is Energy？
![スクリーンショット 2017-07-19 17.14.54.png](https://qiita-image-store.s3.amazonaws.com/0/192913/60a0032a-9e5b-585e-4bc8-a46286e12829.png)
Overhead：Bring Hardware Up、ハードウェアの起動消費電力（軽い処理も重い処理も同じ消費量）

#電力消費の元
・CPU
・通信
・画面
・位置情報

#省エネの原則
・Identify：必要なタイミングで必要なタスクを実行する
・Optimize：処理を最適化する
・Coalesce：タスクをまとめる
・Reduce：同じタスクを減らす

##事例１：Feedを更新
###改善前：Timerでデータを更新する
![スクリーンショット 2017-07-19 17.51.12.png](https://qiita-image-store.s3.amazonaws.com/0/192913/017e2898-89b1-db1c-ed60-76da9b5c554d.png)

###改善ポイント
・ユーザーインターアクションの時更新する
・Notificationが届いている時に更新する
・ネットワーク状態をチェックしてから更新する

```
// Setup NSURLSession Default Session 
let config = URLSessionConfiguration.default() 
// Use WaitsForConnectivity 
config.waitsForConnectivity = true 
```

・キャッシュを利用する

```
// NSURLSession Cache 
let cachesDirectoryURL = FileManager.
default().urlsForDirectory(.cachesDirectory, inDomains: .userDomainMask).first!   
let cacheURL = try! cachesDirectoryURL.appendingPathComponent("MyCache")
var diskPath = cacheURL.path 
let cache = URLCache(memoryCapacity:16384, diskCapacity: 268435456, diskPath: diskPath) 
config.urlCache = cache 
config.requestCachePolicy = .useProtocolCachePolicy
```

![スクリーンショット 2017-07-19 17.54.31.png](https://qiita-image-store.s3.amazonaws.com/0/192913/549b209b-74e5-a9c6-a463-69ebf19d70c0.png)

##事例２：写真をアップロード
###改善前
- 即時アップロード
- エラーの時リトライ
![スクリーンショット 2017-07-20 10.42.22.png](https://qiita-image-store.s3.amazonaws.com/0/192913/841dfceb-f131-fd9e-4e79-7d7efa748a2c.png)

###改善ポイント
- リトライ回数を減らす
- まとめてアップロード
- タイムアウトを適当に設定する
- リトライの制限回数に至りましたら、Background Sessionを利用する
![スクリーンショット 2017-07-20 10.51.20.png](https://qiita-image-store.s3.amazonaws.com/0/192913/41b596cf-3108-b5f4-aa57-8d7771c96bb0.png)

##事例３：分析データをアップロード
NSURLSession Background Sessionを推奨

- 自動リトライ
- スループット監視
- Indicate system the best time to do your work

##事例４：Location Best Practices
- 精度を把握する（必要以上の精度を求めないこと）
- なるべくcontinuous locationを利用しない（電力消費が激しいから）
- 使わない時にすぐ位置情報を止める
- Defer location updates（https://developer.apple.com/documentation/corelocation/cllocationmanager/1620547-allowdeferredlocationupdates） 

##事例５：画面処理
- UIが変化された時のみ画面を更新する
- 更新中の要素にぼかしをしないようにする  

##事例６：CPU
- 実行するタスクを明確する
- Do work quickly and efficiently 
- タイマーをなるべく利用しない 
- 余裕を持つ（どうしてもタイマーを利用する際に、間隔を長く設定する）

##事例７：バックグラウンド処理
- Finish work quickly
- Use background app refresh
- Call completion handler（PushKit APIにcompletion handlerが追加された。）

![スクリーンショット 2017-07-20 12.08.33.png](https://qiita-image-store.s3.amazonaws.com/0/192913/a2208f9f-b8bd-b6a5-8897-806ebc275169.png)

![スクリーンショット 2017-07-20 12.09.02.png](https://qiita-image-store.s3.amazonaws.com/0/192913/0c689d66-a4d2-dedc-ccbc-bc4246119d5a.png)

#消費電力のデバッグツール
##Xcodeのデバッグツール
![スクリーンショット 2017-07-20 12.21.19.jpg](https://qiita-image-store.s3.amazonaws.com/0/192913/a0091a9d-9898-1da6-fca6-06e47be1d2c4.jpeg)
Energy ImpactがVery High（赤）以下の状態は理想です。

さらにInstrumentsに連携も可能
![スクリーンショット 2017-07-20 12.20.10.jpg](https://qiita-image-store.s3.amazonaws.com/0/192913/fafa2a85-9b4f-d7db-3673-68900125712f.jpeg)

Time ProfileからメソッドのCPU使用状況を調べる
![スクリーンショット 2017-07-21 10.59.16.png](https://qiita-image-store.s3.amazonaws.com/0/192913/7b3fa591-372d-cd4d-d201-795d6b0ccfa4.png)

##Scenarios for Energy Debugging
#####General/common
- Launch and Idle 
- Background

#####Application specific （For example, Navigation App ）
- Search for an address 
- Get directions 
- Navigate

#まとめ
- NSURLSession Background Sessionを利用
- continuous locationの利用を控え
- Timerを利用しない
- タスクをまとめて実行する
- Use energy gauges（Xcodeのツール）

#参考
https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/index.html#//apple_ref/doc/uid/TP40015243-CH3-SW1
https://devstreaming-cdn.apple.com/videos/wwdc/2017/238a3uic99uf9c6iw3/238/238_writing_energy_efficient_apps.pdf