Help us understand the problem. What is going on with this article?

SwiftでPush通知

More than 5 years have passed since last update.

※iOS8でのやり方がわかったので一番下に追記しました

SwiftでPush通知を実装してみました。
証明書の取得等はこちらを参考にしています。

【iOSでプッシュ通知を実装する方法の超詳細まとめ(前編)】
http://www.lancork.net/2013/08/how-to-ios-push-first/

【iOSでプッシュ通知を実装する方法の超詳細まとめ(後編)】
http://www.lancork.net/2013/08/how-to-ios-push-second/

元記事:http://sawapi.hatenablog.com/entry/2014/06/08/230719

コードの解説

Push通知を有効にする

func application( application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary? ) -> Bool {

    application.registerForRemoteNotificationTypes(
        UIRemoteNotificationType.Badge | 
        UIRemoteNotificationType.Sound |
        UIRemoteNotificationType.Alert )

    return true
}

AppDelegate.swiftのapplication didFinishLaunchingWithOptionsにて
application.registerForRemoteNotificationTypesを呼び出し、有効にするものを指定します。

  • UIRemoteNotificationType.Badge・・・アイコンバッジ
  • UIRemoteNotificationType.Sound・・・Push通知時になる音
  • UIRemoteNotificationType.Alert・・・Push通知時に表示される文字列

上記の処理が成功するとapplication didRegisterForRemoteNotificationsWithDeviceTokenが呼ばれるのでその中でデバイストークンを取得します。

デバイストークンの取得

func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData ) {

    // <>と" "(空白)を取る
    var characterSet: NSCharacterSet = NSCharacterSet( charactersInString: "<>" )

    var deviceTokenString: String = ( deviceToken.description as NSString )
                                        .stringByTrimmingCharactersInSet( characterSet )
                                        .stringByReplacingOccurrencesOfString( " ", withString: "" ) as String

    println( deviceTokenString )

}

devideToken.descriptionには、

<00000000 11111111 22222222 33333333 aaaaaaaa bbbbbbbb cccccccc dddddddd>

というような文字列で入っているため、"<"と">"と" (スペース)"を取る必要があります。
Swiftの文字の整形の仕方が分からず、、一旦NSStringに変換し、余分な文字を取り除きました。
( いい方法がありましたら教えて下さい。。。)

上記までを実行するとデバイストークンを取得できるのでメモしておきます。

Push通知が届くかテスト

Push通知がちゃんと届くかテストするために以下のスクリプトでテストしてみました。

<?php
$deviceToken = '************';

// 送信する文字列
$alert = 'Push test.';

// バッジ
$badge = 1;

$body = array();
$body['aps'] = array( 'alert' => $alert );
$body['aps']['badge'] = $badge;

// SSL証明書
$cert = '********.pem';

$url = 'ssl://gateway.sandbox.push.apple.com:2195'; // 開発用
//$url = 'ssl://gateway.push.apple.com:2195'; // 本番用

$context = stream_context_create();
stream_context_set_option( $context, 'ssl', 'local_cert', $cert );
$fp = stream_socket_client( $url, $err, $errstr, 60, STREAM_CLIENT_CONNECT, $context );

if( !$fp ) {

    echo 'Failed to connect.' . PHP_EOL;
    exit( 1 );

}

$payload = json_encode( $body );
$message = chr( 0 ) . pack( 'n', 32 ) . pack( 'H*', $deviceToken ) . pack( 'n', strlen($payload ) ) . $payload;

print 'send message:' . $payload . PHP_EOL;

fwrite( $fp, $message );
fclose( $fp );

以下のように通知がきたら成功です。
screenshot_push.png

ソースコード

gistにあげました。
https://gist.github.com/sawapi/a7cee65e4ad95578044d

(´・ω・`)

ここまで書いて気づいたんですが、registerForRemoteNotificationTypesメソッドは
iOS8からDeprecatedになってるんですね。。。
試しに新しいやり方でやってみましたがうまくいかない、、というか
やり方がよくわかりませんでした。

var types: UIUserNotificationType = UIUserNotificationType.Badge |
                                   UIUserNotificationType.Alert |
                                   UIUserNotificationType.Sound


var settings: UIUserNotificationSettings = UIUserNotificationSettings.settingsForTypes( types, categories: nil )
application.registerUserNotificationSettings( settings )

application.registerForRemoteNotifications()

これでできると思ったんですが、こんなエラーがでます(´・ω・`)

'settingsForTypes' is unavailable: use object construction 'UIUserNotificationSettings(forTypes:categories:)'
UIUserNotificationSettings.settingsForTypes

Objective-Cだとこんな感じでうまくいってるみたいなんですが。。
http://stackoverflow.com/questions/24049266/get-the-push-notification-list-on-ios8

やり方わかったら書き直します(´・ω・`)

※6/13追記
やり方分かりました。
エラーログにちゃんと書いてあるのに気付かなかった。。。

func application( application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary? ) -> Bool {

    var types: UIUserNotificationType = UIUserNotificationType.Badge |
        UIUserNotificationType.Alert |
        UIUserNotificationType.Sound

    var settings: UIUserNotificationSettings = UIUserNotificationSettings( forTypes: types, categories: nil )

    application.registerUserNotificationSettings( settings )
    application.registerForRemoteNotifications()

    return true
}

これでできそうですー!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away