82
Developers.IO 2016 2 田中 孝明 モバイルアプリサービス部 Ⓒ Classmethod, Inc. 2016年04月23日 AndroidーiOS開発比較~iOSエン ジニアから見たAndroidのアレコレ~ 1

AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Embed Size (px)

Citation preview

Page 1: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Developers.IO 2016

2

田中 孝明 モバイルアプリサービス部

Ⓒ Classmethod, Inc.

2016年04月23日

AndroidーiOS開発比較~iOSエンジニアから見たAndroidのアレコレ~

1

Page 2: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

自己紹介• 田中孝明 • http://dev.classmethod.jp/author/tanaka-takaaki/

• モバイルアプリサービス部所属 • iOS開発担当

2Ⓒ Classmethod, Inc.

Page 3: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

愛知県に住んでいたことあります

3Ⓒ Classmethod, Inc.

Page 4: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

弊社のよくある要件

• Android / iOS並行開発 • 同時リリース • iOS先行リリースという案件もあり • Appleの審査期間を踏まえてiOSを前倒しで開発するということもあり

4Ⓒ Classmethod, Inc.

Page 5: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

弊社のよくある開発体制

5Ⓒ Classmethod, Inc.

Android / iOS開発者間でコードレビューを行うこともある

Page 6: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

本題

6Ⓒ Classmethod, Inc.

Page 7: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

モバイル開発において注意する点

• 対応OSバージョンについて • 共通のドキュメントについて • 実装方針について

7Ⓒ Classmethod, Inc.

Page 8: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

モバイル開発において注意する点

• 対応OSバージョンについて • 共通のドキュメントについて • 実装方針について

8Ⓒ Classmethod, Inc.

Page 9: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

対応OSバージョンについて• Android

9Ⓒ Classmethod, Inc.

http://developer.android.com/intl/ja/about/dashboards/index.html

Page 10: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

対応OSバージョンについて• Android • 4.x系はシェアが20%程度あるのでサポートせざるを得ない状況が多い

• 4.4からはWebViewがChoromeベースに変更されているため、WebViewを利用する案件は注意が必要

10Ⓒ Classmethod, Inc.

Page 11: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

対応OSバージョンについて• iOS

11Ⓒ Classmethod, Inc.

https://developer.apple.com/support/app-store/jp/

Page 12: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

対応OSバージョンについて• iOS • Swiftで新規で作成する場合はiOS 8以上推奨 • Swift+CocoaPodsでEmbed frameworkが利用できるため

• ひとつ前のバージョン(iOS 8)対応で95%のシェアは確保できる

12Ⓒ Classmethod, Inc.

Page 13: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

対応OSバージョンについて• iOS • Xcode のバージョンアップ対応には注意 • XcodeのバージョンによってサポートされるSwiftのバージョンが違う • Xcode 6.0 -> Swift 1.0 • Xcode 6.1 -> Swift 1.1 • Xcode 6.3 -> Swift 1.2 • Xcode 7.0 -> Swift 2.0 • Xcode 7.2 -> Swift 2.1 • Xcode 7.3 -> Swift 2.2

13Ⓒ Classmethod, Inc.

Page 14: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

対応OSバージョンについて• Android • 対応OSは多い • WebView対応に注意 • BLE案件に注意

• iOS • Swiftのバージョンに注意 • ATS対応

14Ⓒ Classmethod, Inc.

Page 15: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

モバイル開発において注意する点

• 対応OSバージョンについて • 共通のドキュメントについて • 実装方針について

15Ⓒ Classmethod, Inc.

Page 16: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

共通のドキュメントについて

16Ⓒ Classmethod, Inc.

• お客様と開発側間でアプリの機能を実現するために必要なものを洗い出しておく

• Android / iOS開発者の間でも共通の認識を持てるドキュメントを作成しておく

Page 17: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

共通のドキュメントについて

17Ⓒ Classmethod, Inc.

Page 19: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

モバイル開発において注意する点

• 対応OSバージョンについて • 共通のドキュメントについて • 実装方針について

19Ⓒ Classmethod, Inc.

Page 20: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

実装方針について• 開発環境、実装方針については初期段階で決定しておく

• 決定した内容はドキュメントとして残しておく • 開発環境→GitHubのREADMEに記載 • 実装方針→Wikiに記載

• 新たなチームメンバーが加わった際に一覧で確認できるドキュメントを整備しておく(Wiki等を活用) • API仕様や要件定義、設計の資料が一覧で確認できるようにしておく

20Ⓒ Classmethod, Inc.

Page 21: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

実装方針の共有

21Ⓒ Classmethod, Inc.

パッケージ名

ui viewなどの画面表示に関わるクラスをまとめる

domainviewの表示に関わるロジックや、エンティティなど

のモデルクラスをまとめる

infra API通信、DBアクセス、データ保存をまとめる

• パッケージ分類の一例(※あくまで一例です)

Page 22: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

それぞれの部品をどこに配置するか…?

22Ⓒ Classmethod, Inc.

Page 23: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

ui

23Ⓒ Classmethod, Inc.

Page 24: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

ui

24Ⓒ Classmethod, Inc.

Page 25: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

domain

25Ⓒ Classmethod, Inc.

Page 26: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

domain

26Ⓒ Classmethod, Inc.

Page 27: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

infra

27Ⓒ Classmethod, Inc.

Page 28: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

infra

28Ⓒ Classmethod, Inc.

Page 29: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

実装方針について• 画面の作成方法に関してはOSに依存しているところが大きいので、レビューできるようになるまで時間がかかる

• プルリクエストには修正した画面のスクリーンショットを貼ってもらう

• Android • XMLファイルをゴリゴリ編集する

• iOS • StoryBoardを使う

29Ⓒ Classmethod, Inc.

Page 30: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

実装方針について

30Ⓒ Classmethod, Inc.

Page 31: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

実装方針について

31Ⓒ Classmethod, Inc.

Page 32: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

実装方針について• 各部品の担当範囲を明確にすることでコードレビューの際に部品を理解するまでのコストを軽減する

• ロジック、モデルを分離することでAndroid / iOS開発者がコードレビューできる範囲を増やす

• 実装漏れを無くす

32Ⓒ Classmethod, Inc.

Page 33: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

アレコレありますが 結局は自ら手を動かして実装して

いかないと身につかない

33Ⓒ Classmethod, Inc.

Page 34: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

自ら手を動かす

34

Page 35: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Push通知を AndroidとiOSで 実装してみる

35

Page 36: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

36

Page 37: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Push通知を実装してみる• Pushサービスの登録 • GCM(Google Cloud Messaging) • APNS(Apple Push Notification Service)

• Push通知の作成 • Pushメッセージを作成

• Push通知の受信 • OS毎に受信処理を行う

37Ⓒ Classmethod, Inc.

Page 38: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Push通知を実装してみる

38Ⓒ Classmethod, Inc.

https://aws.amazon.com/jp/sns/

Amazon Simple Notification Service (SNS)

Page 39: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Android側の作業

39Ⓒ Classmethod, Inc.

• GCMへの登録 • ライブラリのインポート • パーミッションの設定 • Push受信処理の実装 • Amazon Cognito IDの取得 • Amazon SNSへトークンの送信 • 受信時の処理の実装

Page 40: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

iOS側の作業

40Ⓒ Classmethod, Inc.

• APNSへの登録 • ライブラリのインポート • Amazon Cognito IDの取得 • Amazon SNSへトークンの送信 • 受信時の処理

Page 41: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

AWS側の作業

41Ⓒ Classmethod, Inc.

• Amazon Cognito で Identity pool を作成 • Amazon SNS で Google Android の Platformを作成

• Amazon SNS で Apple iOS Dev の Platformを作成

• Amazon SNS で Topicを作成

Page 42: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

開発環境• Android • Android Studio 2.0 • Java

• iOS • Xcode 7.3 • CocoaPods or Carthage • Swift 2.2

42Ⓒ Classmethod, Inc.

Page 43: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Android側の作業

43Ⓒ Classmethod, Inc.

• GCMへの登録 • ライブラリのインポート • 設定ファイルのインポート • パーミッションの設定 • Push受信処理の実装 • Amazon Cognito IDの取得 • Amazon SNSへトークンの送信 • 受信時の処理の実装

Page 44: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

GCMへの登録

44Ⓒ Classmethod, Inc.

https://developers.google.com/cloud-messaging/

Page 45: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

GCMへの登録

45Ⓒ Classmethod, Inc.

• google-services.jsonをダウンロードする

Page 46: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

GCMへの登録

46Ⓒ Classmethod, Inc.

• google-services.jsonをプロジェクトに追加する

Page 47: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

ライブラリのインポート

47Ⓒ Classmethod, Inc.

… android { …} dependencies {

… compile 'com.amazonaws:aws-android-sdk-cognito:2.+' compile 'com.amazonaws:aws-android-sdk-sns:2.+'}

• build.gradleを編集 • AWSのSDKを指定する

Page 48: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

ライブラリのインポート

48Ⓒ Classmethod, Inc.

apply plugin: 'com.google.gms.google-services'android { …} dependencies { … compile "com.google.android.gms:play-services:8.3.0" … }

• build.gradleを編集 • GCM用のライブラリを適用する

Page 49: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

ライブラリのインポート

49Ⓒ Classmethod, Inc.

• Android Studioからライブラリをインポートする • 「Sync Project with Gradle Files」を実行する

Page 50: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

パーミッションの設定

50Ⓒ Classmethod, Inc.

<?xml version="1.0" encoding="utf-8"?><manifest package="jp.co.kongmings.android.app" xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="com.google.android.c2dm.permission.REGISTER" /> </manifest>

• AndroidManifest.xmlを編集 • パーミッションの設定

Page 51: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Push受信処理の実装

51Ⓒ Classmethod, Inc.

<application … <receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <category android:name="jp.co.kongmings.android.app" /> </intent-filter> </receiver> <service android:name=".infra.service.MsgGcmListenerService" android:exported="false" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> </intent-filter> </service> <service android:name=".infra.service.RegistrationIntentService" android:exported="false" /> <service android:name=".infra.service.MsgInstanceIDListenerService" android:exported="false"> <intent-filter> <action android:name="com.google.android.gms.iid.InstanceID"/> </intent-filter> </service> </application>

• AndroidManifest.xmlを編集

Page 52: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Push受信処理の実装

52Ⓒ Classmethod, Inc.

public class MsgGcmListenerService extends GcmListenerService { static final String TAG = MsgGcmListenerService.class.getSimpleName(); @Override public void onMessageReceived(String from, Bundle data) { String message = data.getString("message"); sendNotification(message); sendBroadcast(message); } void sendNotification(String message) { Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("Message received!") .setContentText(message) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(0, notificationBuilder.build()); } void sendBroadcast(String message) { Intent broadcastIntent = new Intent(); broadcastIntent.putExtra("message", message); broadcastIntent.setAction("MESSAGE_RECEIVED"); getBaseContext().sendBroadcast(broadcastIntent); }}

• GCMからメッセージが返ってきた時の処理

Page 53: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Push受信処理の実装

53Ⓒ Classmethod, Inc.

… void sendNotification(String message) { Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("Message received!") .setContentText(message) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(0, notificationBuilder.build()); } ...

• 通知センターに表示させる

Page 54: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Push受信処理の実装

54Ⓒ Classmethod, Inc.

public class MsgGcmListenerService extends GcmListenerService { … void sendBroadcast(String message) { Intent broadcastIntent = new Intent(); broadcastIntent.putExtra("message", message); broadcastIntent.setAction("MESSAGE_RECEIVED"); getBaseContext().sendBroadcast(broadcastIntent); }}

• メッセージを受信したことを通知する

Page 55: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Push受信処理の実装

55Ⓒ Classmethod, Inc.

public class RegistrationIntentService extends IntentService { public RegistrationIntentService() { super("RegistrationIntentService"); } @Override protected void onHandleIntent(Intent intent) { if (intent != null) { try { InstanceID instanceID = InstanceID.getInstance(this); String token = instanceID.getToken( getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); Prefs.put("token", token); } catch (IOException e) { e.printStackTrace(); } } }}

• トークン取得処理にてトークンを保持しておく

Page 56: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Amazon Cognito IDの取得

56Ⓒ Classmethod, Inc.

void getCognitoId() { new Thread(new Runnable() { @Override public void run() { CognitoCachingCredentialsProvider provider =          new CognitoCachingCredentialsProvider( self, COGNITO_IDENTITY_POOL_ID, AWS_REGION ); final String identityId = provider.getIdentityId(); Prefs.put("cognito_id", identityId); } }).start();}

• CognitoCachingCredentialsProviderにCognito Identity Pool IDを指定する

Page 57: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Amazon SNSへトークンの送信

57Ⓒ Classmethod, Inc.

void sendToken() { AmazonSNSClient snsClient = new AmazonSNSClient(mProvider); snsClient.setRegion(Region.getRegion(AWS_REGION)); CreatePlatformEndpointRequest createRequest = new CreatePlatformEndpointRequest(); createRequest.setPlatformApplicationArn(AWS_SNS_APPLICATION_ARN); String token = Prefs.get("token"); createRequest.setToken(token); CreatePlatformEndpointResult platformEndpoint = snsClient.createPlatformEndpoint(createRequest); String endpointArn = platformEndpoint.getEndpointArn(); snsClient.subscribe(AWS_SNS_SUBSCRIBE_TOPIC_ARN, "application", endpointArn);}

• 指定したTopicをSuscribeする

Page 58: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

受信時の処理の実装

58Ⓒ Classmethod, Inc.

private MessageBroadcastReceiver mReceiver; public class MessageBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); String message = bundle.getString("message"); Toast.makeText(context, message, Toast.LENGTH_LONG).show(); }} @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); … mReceiver = new MessageBroadcastReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("MESSAGE_RECEIVED"); registerReceiver(mReceiver, intentFilter);}

Page 59: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

iOS側の作業

59Ⓒ Classmethod, Inc.

• APNSへの登録 • ライブラリのインポート • Amazon Cognito IDの取得 • Amazon SNSへトークンの送信 • 受信時の処理

Page 60: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

APNSへの登録

60Ⓒ Classmethod, Inc.

https://developer.apple.com/jp/documentation/RemoteNotificationsPG.pdf

Page 61: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

APNSへの登録

61Ⓒ Classmethod, Inc.

• キーチェーンアクセスを起動して認証局に証明書を要求する

Page 62: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

APNSへの登録

62Ⓒ Classmethod, Inc.

Page 63: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

APNSへの登録

63Ⓒ Classmethod, Inc.

Page 64: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

APNSへの登録

64Ⓒ Classmethod, Inc.

https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/

Chapters/ApplePushService.html

Page 65: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

APNSへの登録

65Ⓒ Classmethod, Inc.

• Provisioning Profileが正しく指定されているか確認する

Page 66: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

ライブラリのインポート

66Ⓒ Classmethod, Inc.

platform :ios, '8.0' use_frameworks!

target 'App' do pod 'AWSSNS' end

• CocoaPods経由でインポートする • Podfileを編集

Page 67: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

ライブラリのインポート

67Ⓒ Classmethod, Inc.

• CocoaPods経由でインポートする • pod installコマンドを実行

➜ app git:(develop) ✗ bundle exec pod install

Page 68: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Amazon Cognito IDの取得

68Ⓒ Classmethod, Inc.

func application( application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let credentialsProvider = AWSCognitoCredentialsProvider( regionType: AWSRegionType.APNortheast1, identityPoolId: CognitoIdentityPoolId) let defaultServiceConfiguration = AWSServiceConfiguration( region: AWSRegionType.APNortheast1, credentialsProvider: credentialsProvider) AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration

self.registerForRemoteNotifications() return true }

• AWSServiceManagerの設定を実施 • CognitoIdentityPoolIdはAWSで作成したものを指定する

Page 69: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Amazon SNSへトークンの送信

69Ⓒ Classmethod, Inc.

func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { let deviceTokenString = "\(deviceToken)" .stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString:"<>")) .stringByReplacingOccurrencesOfString(" ", withString: "") …

}

• トークン取得時に呼ばれるメソッドからトークンを取得する

Page 70: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Amazon SNSへトークンの送信

70Ⓒ Classmethod, Inc.

… let sns = AWSSNS.defaultSNS() let request = AWSSNSCreatePlatformEndpointInput() request.token = deviceTokenString request.platformApplicationArn = AWSSNSApplicationArn sns.createPlatformEndpoint(request).continueWithExecutor( AWSExecutor.mainThreadExecutor(), withBlock: { (task: AWSTask!) -> AnyObject! in if task.error != nil { print("Error: \(task.error)") } else { let createEndpointResponse = task.result as! AWSSNSCreateEndpointResponse let subscribeRequest = AWSSNSSubscribeInput() subscribeRequest.topicArn = self.AWSSNSSubscribeTopicArn subscribeRequest.endpoint = createEndpointResponse.endpointArn subscribeRequest.protocols = "Application" sns.subscribe(subscribeRequest) } return nil }) }

• 指定したTopicをSuscribeする

Page 71: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

受信時の処理

71Ⓒ Classmethod, Inc.

func application( application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) { if application.applicationState == .Active { if let aps = userInfo["aps"] { if let alert = aps["alert"] { let alertController = UIAlertController( title: nil, message: alert, preferredStyle: .Alert) alertController.addAction( UIAlertAction( title: "OK", style: .Default, handler: nil)) self.window?.rootViewController?.presentViewController( alertController, animated: true, completion: nil) } } } }

• Pushを受信した時の処理を記載する

Page 72: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

AWS側の作業

72Ⓒ Classmethod, Inc.

• Amazon Cognito で Identity pool を作成 • Amazon SNS で Google Android の Platformを作成

• Amazon SNS で Apple iOS Dev の Platformを作成

• Amazon SNS で Topicを作成

Page 73: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Amazon Cognito で Identity pool を作成

73Ⓒ Classmethod, Inc.

http://aws.amazon.com/jp/cognito/

Page 74: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Amazon Cognito で Identity pool を作成

74Ⓒ Classmethod, Inc.

Page 75: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Amazon SNS で Google Android の Platformを作成

75Ⓒ Classmethod, Inc.

https://aws.amazon.com/jp/sns/

Page 76: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Amazon SNS で Apple iOS Dev の Platformを作成

76Ⓒ Classmethod, Inc.

https://aws.amazon.com/jp/sns/

Page 77: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Amazon SNS で Topicを作成

77Ⓒ Classmethod, Inc.

https://aws.amazon.com/jp/sns/

Page 78: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

DEMO

78Ⓒ Classmethod, Inc.

Page 79: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

79Ⓒ Classmethod, Inc.

Page 80: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

80Ⓒ Classmethod, Inc.

Page 81: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

まとめ

81Ⓒ Classmethod, Inc.

• 共通のドキュメントを用意する • ノイズを減らして開発者同士がコードレビューできる範囲を増やす

• 手を動かす

Page 82: AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜

Developers.IO 2016

ご静聴ありがとうございました。 スライドは後日ブログで公開します。

82

A-1

Ⓒ Classmethod, Inc.

#cmdevio2016