スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
このエントリーをはてなブックマークに追加

[cakePHP]cakePHPにEasyAPNsを導入する

必要なもの
・サーバ(今回はMySQLを想定している)
cakePHP2.5.2(2.x系ならどれでもいいと思います)
EasyAPNs
・PEMファイル4つ
こちらの手順でDevelopmentとProduction両方の、 証明書.pem秘密鍵.pem を手に入れます)

手順1:VendorフォルダにEasyAPNsを入れる
zipでダウンロードしたEasyAPNsを解凍し、srcの下にあるphpフォルダを改名して、easyapnsとします。(名前は任意でよい)
その後、easyapnsフォルダごとcakephpのVendorフォルダ以下に入れます。
app/Vendor/easyapns と言う形にしてください。

手順2:EasyAPNsのログファイルも作る
cakephpのtmpフォルダ以下にあるfilesフォルダ以下にapns.logを作成してください。(空ファイルでよい)
app/tmp/files/apns.log と言う形にしてください。

手順3:プッシュ通知機能を実装するController,Model,Viewを作る
それぞれ以下ような内容のファイルを作成します。
Controller/PushNotificationsController.php※1
<?php
App::uses('AppController', 'Controller');
App::uses('ConnectionManager', 'Model');
//easyapns読み込み
App::import('Vendor','easyapns/classes/class_APNS');
App::import('Vendor','easyapns/classes/class_DbConnect');

class PushNotificationsController extends AppController {

public function index() {
// フォームからポストされたデータがあるかどうか
if ($this->request->is('post')) {
if(!empty($this->request->data)) {
// messageが空で送信されてないかどうか
if(!empty($this->request->data['PushNotification']['message'])) {
$this->samples();
$this->Session->setFlash('message:'.$this->request->data['PushNotification']['message']);
return $this->redirect('index');
}
}
}
}

public function samples() {
error_reporting(0);

$source = ConnectionManager::getDataSource($this->PushNotification->useDbConfig);
$db = new DbConnect($source->config['host'],
$source->config['login'],
$source->config['password'],
$source->config['database']);
$db->show_errors();

// FETCH $_GET OR CRON ARGUMENTS TO AUTOMATE TASKS
$apns = new APNS($db);

/**
/* ACTUAL SAMPLES USING THE 'Examples of JSON Payloads' EXAMPLES (1-5) FROM APPLE'S WEBSITE.
* LINK: http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW15
*/

// APPLE APNS EXAMPLE 1
$apns->newMessage(1);
$apns->addMessageAlert('Message received from Bob');
$apns->addMessageCustom('acme2', array('bang', 'whiz'));
$apns->queueMessage();

// APPLE APNS EXAMPLE 2
$apns->newMessage(1, '2010-01-01 00:00:00'); // FUTURE DATE NOT APART OF APPLE EXAMPLE
$apns->addMessageAlert('Bob wants to play poker', 'PLAY');
$apns->addMessageBadge(5);
$apns->addMessageCustom('acme1', 'bar');
$apns->addMessageCustom('acme2', array('bang', 'whiz'));
$apns->queueMessage();

// APPLE APNS EXAMPLE 3
$apns->newMessage(1);
$apns->addMessageAlert('You got your emails.');
$apns->addMessageBadge(9);
$apns->addMessageSound('bingbong.aiff');
$apns->addMessageCustom('acme1', 'bar');
$apns->addMessageCustom('acme2', 42);
$apns->queueMessage();

// APPLE APNS EXAMPLE 4
$apns->newMessage(1, '2010-01-01 00:00:00'); // FUTURE DATE NOT APART OF APPLE EXAMPLE
$apns->addMessageAlert(NULL, NULL, 'GAME_PLAY_REQUEST_FORMAT', array('Jenna', 'Frank'));
$apns->addMessageSound('chime');
$apns->addMessageCustom('acme', 'foo');
$apns->queueMessage();

// APPLE APNS EXAMPLE 5
$apns->newMessage(1);
$apns->addMessageCustom('acme2', array(5, 8));
$apns->queueMessage();

// SEND MESSAGE TO MORE THAN ONE USER
$apns->newMessage(array(1,3,4,5,8,15,16));
$apns->addMessageAlert('Greetings Everyone!');
$apns->queueMessage();

// SEND ALL MESSAGES NOW
$apns->processQueue();
}

public function apns() {
/**
* Begin Document
*/
error_reporting(0);

// CREATE DATABASE OBJECT ( MAKE SURE TO CHANGE LOGIN INFO )
$source = ConnectionManager::getDataSource($this->PushNotification->useDbConfig);
$db = new DbConnect($source->config['host'],
$source->config['login'],
$source->config['password'],
$source->config['database']);
$db->show_errors();
// FETCH $_GET OR CRON ARGUMENTS TO AUTOMATE TASKS
$args = (!empty($_GET)) ? $_GET:array('task'=>$argv[1]);

// CREATE APNS OBJECT, WITH DATABASE OBJECT AND ARGUMENTS
$apns = new APNS($db, $args);
}
}

Model/PushNotification.php
<?php
App::uses('Model', 'Model');
class PushNotification extends Model {
public $name = 'PushNotification';
}

View/PushNotifiations/index.ctp※2
<?php echo $this->Form->create('PushNotification');?>
<?php echo $this->Form->input('message',array('label'=>false));?>
<?php echo $this->Form->end('Push Message');?>

View/PushNotifiations/apns.ctp
(このファイルは空ファイル)

※1:apnsメソッドはapns.phpの、samplesはsamples.phpの内容をほぼそのまま移したものです。
※2:inputがありますが、意味はありません。今後改変していく中で、メッセージを送信する際に使えると思って入れています。

手順4:PEMファイルをcakePHPに入れる
webrootフォルダ下のfilesフォルダに対して4つのPEMファイルを入れます。
(Developer・Productionの証明書.pem、秘密鍵.pem)

手順5:EasyAPNsの設定を行う
Vendor/easyapns/classes/class_APNS.phpを書き換えます。
まずは各定義を追加します。
define('LOGPATH',LOGS . DS . 'apns.log');
define('CERTIFICATE',WWW_ROOT . DS . 'files' . DS .'(Production用の証明書.pem)');
define('SANDBOXCERTIFICATE',WWW_ROOT . DS . 'files' . DS .'(Developer用の証明書.pem)');

class APNS {

そして、各項目を今定義したパスに変更します。
//	private $logPath = '/usr/local/apns/apns.log';
private $logPath = LOGPATH;
//	private $certificate = '/usr/local/apns/apns.pem';
private $certificate = CERTIFICATE;
//	private $sandboxCertificate = '/usr/local/apns/apns-dev.pem'; // change this to your development certificate absolute path
private $sandboxCertificate = SANDBOXCERTIFICATE;


手順6:サーバにSQLを流す
EasyAPNsのsrcフォルダ下のsqlフォルダに入っているapns.sql(またはapns_alt.sql)を使用します。
apns.sqlとapns_alt.sqlの違いは、apns_device_historyテーブルの有無だけなのでどちらでもいいです。

手順7:iPhoneアプリを作る
アプリはなんでもよく、AppDelegateに対してコードを追加するだけです。
EasyAPNsのsrcフォルダ下のdelegateフォルダに入っているDelegate.mファイルを開いてください。
始めにapplicationDidFinishLaunchingメソッド(テンプレートでiOSプロジェクトを生成すれば必ずある)に対して以下のコードを追加します。
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
// Add registration for remote notifications
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];

// Clear application badge when app launches
application.applicationIconBadgeNumber = 0;
}

次のコードもAppDelegateに追加します。
ただし、56行目のhostは自分のWebサイトのURL、
61行目のurlStringはapnsアクションに変更してください。(?から後ろのパラメータ群は消さないでそのまま付ける)
/* 
* --------------------------------------------------------------------------------------------------------------
* BEGIN APNS CODE
* --------------------------------------------------------------------------------------------------------------
*/

/**
* Fetch and Format Device Token and Register Important Information to Remote Server
*/
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {

#if !TARGET_IPHONE_SIMULATOR

// Get Bundle Info for Remote Registration (handy if you have more than one app)
NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];

// Check what Notifications the user has turned on. We registered for all three, but they may have manually disabled some or all of them.
NSUInteger rntypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

// Set the defaults to disabled unless we find otherwise...
NSString *pushBadge = (rntypes & UIRemoteNotificationTypeBadge) ? @"enabled" : @"disabled";
NSString *pushAlert = (rntypes & UIRemoteNotificationTypeAlert) ? @"enabled" : @"disabled";
NSString *pushSound = (rntypes & UIRemoteNotificationTypeSound) ? @"enabled" : @"disabled";

// Get the users Device Model, Display Name, Unique ID, Token & Version Number
UIDevice *dev = [UIDevice currentDevice];
NSString *deviceUuid;
if ([dev respondsToSelector:@selector(uniqueIdentifier)])
deviceUuid = dev.uniqueIdentifier;
else {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
id uuid = [defaults objectForKey:@"deviceUuid"];
if (uuid)
deviceUuid = (NSString *)uuid;
else {
CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
deviceUuid = (NSString *)cfUuid;
CFRelease(cfUuid);
[defaults setObject:deviceUuid forKey:@"deviceUuid"];
}
}
NSString *deviceName = dev.name;
NSString *deviceModel = dev.model;
NSString *deviceSystemVersion = dev.systemVersion;

// Prepare the Device Token for Registration (remove spaces and < >)
NSString *deviceToken = [[[[devToken description]
stringByReplacingOccurrencesOfString:@"<"withString:@""]
stringByReplacingOccurrencesOfString:@">" withString:@""]
stringByReplacingOccurrencesOfString: @" " withString: @""];

// Build URL String for Registration
// !!! CHANGE "www.mywebsite.com" TO YOUR WEBSITE. Leave out the http://
// !!! SAMPLE: "secure.awesomeapp.com"
NSString *host = @"www.mywebsite.com";

// !!! CHANGE "/apns.php?" TO THE PATH TO WHERE apns.php IS INSTALLED
// !!! ( MUST START WITH / AND END WITH ? ).
// !!! SAMPLE: "/path/to/apns.php?"
NSString *urlString = [NSString stringWithFormat:@"/apns.php?task=%@&appname=%@&appversion=%@&deviceuid=%@&devicetoken=%@&devicename=%@&devicemodel=%@&deviceversion=%@&pushbadge=%@&pushalert=%@&pushsound=%@", @"register", appName,appVersion, deviceUuid, deviceToken, deviceName, deviceModel, deviceSystemVersion, pushBadge, pushAlert, pushSound];

// Register the Device Data
// !!! CHANGE "http" TO "https" IF YOU ARE USING HTTPS PROTOCOL
NSURL *url = [[NSURL alloc] initWithScheme:@"http" host:host path:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *urlR, NSData *returnData, NSError *e) {
NSLog(@"Return Data: %@", returnData);

}];

NSLog(@"Register URL: %@", url);

#endif
}

/**
* Failed to Register for Remote Notifications
*/
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {

#if !TARGET_IPHONE_SIMULATOR

NSLog(@"Error in registration. Error: %@", error);

#endif
}

/**
* Remote Notification Received while application was open.
*/
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

#if !TARGET_IPHONE_SIMULATOR

NSLog(@"remote notification: %@",[userInfo description]);
NSDictionary *apsInfo = [userInfo objectForKey:@"aps"];

NSString *alert = [apsInfo objectForKey:@"alert"];
NSLog(@"Received Push Alert: %@", alert);

NSString *sound = [apsInfo objectForKey:@"sound"];
NSLog(@"Received Push Sound: %@", sound);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

NSString *badge = [apsInfo objectForKey:@"badge"];
NSLog(@"Received Push Badge: %@", badge);
application.applicationIconBadgeNumber = [[apsInfo objectForKey:@"badge"] integerValue];

#endif
}

/*
* --------------------------------------------------------------------------------------------------------------
* END APNS CODE
* --------------------------------------------------------------------------------------------------------------
*/


手順8:プッシュ通知する
実際にプッシュ通知してみます。
・iPhoneにアプリケーションをビルドして実行します。
・xcodeのログに返ってきたデータのログが表示されます。
・サーバのapns_devicesテーブルにアプリをビルド実行したiPhoneデバイスの情報が登録されます。
・登録されたiPhoneデバイスのデータのdevelopmentカラムをsandboxに変更します。
・push_notifications/indexにアクセスして、適当なデータを入力してPostしてください。
・samplesメソッドが実行され、プッシュ通知が飛んできます(Message received from Bobという通知メッセージが表示)


ここまできたら、作業は完了しました。
このエントリーをはてなブックマークに追加

コメントの投稿

非公開コメント

Translation


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。
プロフィール

チーズくん

Author:チーズくん
個人的メモをただ羅列しています。
twitter:@cheese1038

バロメーター
最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。