iOS tech videoのArchitecting Modern Apps, Part 2のまとめ


https://developer.apple.com/tech-talks/videos/

## ざっくり
前半は、A7(64-bit)の話とM7(Motion Coprocessor)の話
後半は、iOS6対応するためのチェックポイントと、うまく対応するためのパターンの紹介。

## A7
プリミティブ型は以下のように違う
![スクリーンショット 2014-01-26 5.03.07.png](https://qiita-image-store.s3.amazonaws.com/0/4585/8b042829-2cb0-f4d9-4c03-8383346cfed2.png "スクリーンショット 2014-01-26 5.03.07.png")

Mismatched Types

``` bad
int myInt = [myNumber integerValue];
```
``` good
NSInteger myInteger = [myNumber integerValue];
```

Mismatched Sizes

``` bad
long myLong = 5000000000;
memcpy(buffer, &myLong, 4);

// buffer contains 4294967296
```
``` good
long myLong = 5000000000;
memcpy(buffer, &myLong, sizeof(long));
// buffer contains 5000000000
```

Mismatched Formats

``` bad
long myLong = 5000000000;NSString *s = [NSString stringWithFormat:@”%d”, myLong];
// s = @”705032704”
```
``` good
long myLong = 5000000000;NSString *s = [NSString stringWithFormat:@”%ld”, myLong];
// s = @”5000000000”
```

64bitになりメモリ使用量は増加した。

![スクリーンショット 2014-01-26 5.09.22.png](https://qiita-image-store.s3.amazonaws.com/0/4585/e91a0620-61c5-9de9-054a-0a0190c8d493.png "スクリーンショット 2014-01-26 5.09.22.png")

## M7
motion dataを断続的に計測している、加速度、位置情報、コンパス。
CMMotionActivityManagerでは、motionが更新されるごとにも、期間を指定しても、motion dataを取得することができる。

``` motionが更新されるごと
CMMotionActivityManager *m = [CMMotionActivityManager new];[m startActivityUpdatesToQueue:[NSOperationQueue mainQueue]                   withHandler:^(CMMotionActivity *activity) {
}];
```
``` 指定した期間ごと
CMStepCounter *c = [CMStepCounter new];[c startStepCountingUpdatesToQueue:[NSOperationQueue mainQueue]                          updateOn:1                       withHandler:^(NSInteger steps, NSError *error) {}];
```

## iOS6対応のチェックポイント

### Frameworks and classes
iOS7のLibraryはoptionalに。classが存在するか確認する。

``` good
[GCController startWirelessControllerDiscoveryWithCompletionHandler:^{   // Discovery timed out or was stopped}];
```
``` bad
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];[center addObserver:self           selector:@selector(foundController:)               name:GCControllerDidConnectNotification             object:nil];
```
``` good
if (&GCControllerDidConnectNotification != nil) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self           selector:@selector(foundController:)               name:GCControllerDidConnectNotification             object:nil];}
```

### method
methodもない場合がある

``` bad
UIMotionEffect *effect = [self makeNewParallaxMotionEffect];[self.view addMotionEffect:effect];
```
``` good
SEL selector = @selector(addMotionEffect:);if ([self.view respondsToSelector:selector]) {   UIMotionEffect *effect = [self makeNewParallaxMotionEffect];   [self.view addMotionEffect:effect];}
```

### Capabilities
いかのようなCapabilityが追加されているので使う。

``` 例
+[CMMotionActivityManager isActivityAvailable]+[MFMailComposeViewController canSendMail]+[CLLocationManager isMonitoringAvailableForClass:]+[UIPrintInteractionController isPrintingAvailable]-[NSFileManager URLForUbiquityContainerIdentifier:]
```

### check version
```
float versionNumber = floor(NSFoundationVersionNumber);if (versionNumber <= NSFoundationVersionNumber_iOS_6_1) {   // use iOS 6-style appearance} else {   // use iOS 7-style appearance}
```

### Architectures
それぞれのCPUで別の動作をさせる。あまり使わないほうがよい。

```
#if __LP64__// code that will only execute on a 64-bit device#else// code that will only execute on a 32-bit device#endif
```

## うまく対応するためのパターン
if文の数を減らし、よりメンテナンスしやすいコードにするための三つのパターン。

### Clusters
機能をカプセル化することで、処理をまとめる。将来的に32-bitのコードを除去することも簡単。

![スクリーンショット 2014-01-26 5.23.25.png](https://qiita-image-store.s3.amazonaws.com/0/4585/8805b6b7-b992-58a6-f035-2304319cfdf6.png "スクリーンショット 2014-01-26 5.23.25.png")

```
@interface TTDownloadController : NSObject+ (instancetype)downloadController;- (void)startDownload:(TTDownload *)download;
- (void)pauseDownload:(TTDownload *)download;
@end
```

### Data Sources
Clusterの中で、data sourceを定義し、抽象クラスを使って処理をまとめる。

```
@interface TTDownloadController ()
@property (strong) id<TTDownloader> downloader;
@end@implementation TTDownloadController+ (instancetype)downloadController {
    id<TTDownloader> downloader = nil;
    if ([NSURLSession class] != nil) {
        downloader = [[TTURLSessionDownloader alloc] init];
    } else {
        downloader = [[TTURLConnectionDownloader alloc] init];
    }
    return [[self alloc] initWithDownloader:downloader];}@end
```

### Categories
フレームワークのクラスにメソッドを追加して、iOS6対応のための分岐をカプセル化する

```
@interface UIView (TechTalkCompatibility)- (void)tt_addMotionEffect:(UIMotionEffect *)effect;@end

@implementation UIView (TechTalkCompatibility)- (void)tt_addMotionEffect:(UIMotionEffect *)effect {
    if ([self respondsToSelector:@selector(addMotionEffect:)]) {
        [self addMotionEffect:effect];
    }}@end
```