3月 07

いまiPhonePushNotificationで遊びまくってます。

まだ、ソースとか詳しいことを説明できるまで至ってませんが
PushNotification(APNS)を利用するには、
1.iPhone Provision PortalからApp IDsを選択する
2.New APP IDを選択する
3.Descriptionに説明を入れる(APNSなど)
4.Bundle Seed ID (App ID Prefix)は Generate NewでOK
5.Bundle Identifier (App ID Suffix)にApp IDを入力する(*のワイルドカード禁止)
6.作成したApp ID の Configureを選択する
7.Enable for Apple Push Notification serviceにチェックを入れる
8.Development Push SSL CertificateのConfigureを選択
9.Continueを選択。
10.一度ブラウザを放置
11.アプリケーション->ユーティリティ->キーチェインを選択
12.キーチェインアクセス->証明書アシスタント->認証局に証明書を要求
13.メールアドレスと通称を入力
14.ディスクに保存と鍵ペア情報の指定にチェック
15.CertificateSigningRequest.certSigningRequestを保存する。
16.放置していたブラウザを呼び出し、ファイル選択でCertificateSigningRequest.certSigningRequestを選択する
17.しばらくするとDownloadでaps_developer_identity.cerをダウンロードする
18.aps_developer_identity.cerをキーチェインで開く
19.自分の証明書の Apple Development Push Serviceを開き、証明書と秘密鍵を確認する(なければこれを削除してもう一度はじめからやり直す。15.鍵ペアのチェック忘れ)
20.証明書の方を選択して、ファイル->書き出す
21.名前を”Cert”とし、保存先を”ホーム” フォーマットを”.p12″ にする
22.秘密鍵の方も選択して、ファイル->書き出す
22.名前を”Key”とし、保存先を”ホーム” フォーマットを”.p12″ にする
23.アプリケーション->ユーティリティ->ターミナルを起動する
24.以下を実行してp12からpemに変換する

openssl pkcs12 -clcerts -nokeys -in Cert.p12 -out Cert.pem
openssl pkcs12 -nocerts -in Key.p12 -out Key.pem
openssl rsa -in Key.pem -out Key.nokeys.pem
cat Cert.pem Key.nokeys.pem > apns-dev.pem

以上でSSL証明書ができました。

XCodeでiPhoneのWindow-based Applicationを選択する。
Delegate.h

#import <UIKit/UIKit.h>

@interface PushNotificationAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    UILabel	 *label;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UILabel *label;

@end

Delegate.m

//
//  PushNotificationAppDelegate.m
//  PushNotification
//
//  Created by maclin on 10/03/05.
//  Copyright Apple Inc 2010. All rights reserved.
//
/**
 * @file
 * Application delegate implementation.
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://code.google.com/p/apns-php/wiki/License
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to aldo.armiento@gmail.com so we can send you a copy immediately.
 *
 * @version $Id$
 */

#import "PushNotificationAppDelegate.h"
#include <AudioUnit/AudioUnit.h>

@implementation PushNotificationAppDelegate

@synthesize window;
@synthesize label;
#pragma mark -
#pragma mark Application delegate

- (void)applicationDidFinishLaunching:(UIApplication *)application {
	[window makeKeyAndVisible];

#if !TARGET_IPHONE_SIMULATOR
	[application registerForRemoteNotificationTypes:
	 UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
#endif
}

#pragma mark -
#pragma mark Remote notifications

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
	// You can send here, for example, an asynchronous HTTP request to your web-server to store this deviceToken remotely.
	NSLog(@"Did register for remote notifications: %@", deviceToken);
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
	NSLog(@"Fail to register for remote notifications: %@", error);
}

#pragma mark -
#pragma mark Memory management
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

	NSLog(@"*** Notification received:");
//	AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
	[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
	NSDictionary *aps = [userInfo objectForKey:@"aps"];

	NSString *event = [aps objectForKey:@"event"];
	NSLog(@"event: %@", event);
	NSString* name = [aps objectForKey:@"name"];
	NSLog(@"name: %@", name);

	if (![name length] > 0) name = @"Somebody";// No name? No problem.
	if ([event length] > 0 && [event isEqualToString:@"rec"]) {
		NSLog(@"*** Notification is of type EVENT");
		NSString* statusMsg = [NSString stringWithFormat:@"%@%@", name, @" is speaking…"];//#FIX How to display this?
		label.text = statusMsg;
	} else {
		NSString *alert = [aps objectForKey:@"alert"];
		NSLog(@"\talert: %@", alert);
		NSString *sound = [aps objectForKey:@"sound"];
		NSLog(@"\tsound: %@", sound);
		NSString *badge = [aps objectForKey:@"badge"];
		NSLog(@"\tbadge: %@", badge);
		NSString *voice = [aps objectForKey:@"voice"];
		NSLog(@"\tvoice: %@", voice);
		NSString *channel = [aps objectForKey:@"channel"];
		NSLog(@"\tchannel: %@", channel);


//		AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
		[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
		label.text = alert;

		//label.text = [@"Message from" stringByAppendingString:name];

//		NSURL *walkieOnURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"w_on" ofType:@"caf"]];
//		AVAudioPlayer *walkieOnPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:walkieOnURL error: nil];
//		[walkieOnPlayer play];

//		NSURL* voicePathRemote = [NSURL URLWithString: [kPlaybackURL stringByAppendingString:voice]];
//		NSLog(@"Playing voice file from URL: %@", (NSString*)voicePathRemote);

//		NSData *myData = [NSData dataWithContentsOfURL:voicePathRemote];
//		AVAudioPlayer *voicePlayer =[[AVAudioPlayer alloc] initWithData:myData error: nil];
//		voicePlayer.delegate = self;
//		[voicePlayer play];
		[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
	}
}

/**
 * Deallocates the memory occupied.
 */
- (void)dealloc {
	[window release];
	[label  release];
	[super dealloc];
}

@end

とMainWindow.nibにラベルを設置し、ラベルとDelegateのLabelをつなぐ。

コンパイルしてiPhoneに転送する
デバッガを起動して

Did register for remote notifications:

のDeviceTokenを得る。

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

// Get the parameters from http get or from command line
$alert = $_GET['alert'] or $alert = $argv[1] or $alert = 'メッセージ';
$badge = (int)$_GET['badge'] or $badge = (int)$argv[2];
$sound = $_GET['sound'] or $sound = $argv[3];

// Construct the notification payload
$body = array();
$body['aps'] = array('alert' => $alert);
if ($badge)
$body['aps']['badge'] = $badge;
if ($sound)
$body['aps']['sound'] = $sound;
/* End of Configurable Items */

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apns.pem');
// assume the private key passphase was removed.
// stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);

$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
// for production change the server to ssl://gateway.push.apple.com:219
if (!$fp) {
 print "Failed to connect $err $errstr\n";
 return;
}
else {
print "Connection OK\n";
}

$payload = json_encode($body);
$msg = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload;
print "sending message :" . $payload . "\n";
fwrite($fp, $msg);
fclose($fp);
?>

php -f ./apns.phpを実行する。

おつかれさまでした。

Tagged with:
preload preload preload