본문 바로가기

개발도구/iOS - 아이폰 개발

[아이폰] PHP코드로 - 아이폰 PUSH 보내기 총정리

아이폰 PUSH 는 Apple Push Notification Service (APNS) 란다.
쉽게 말하자면 Notification 을 이용한 service 제공인데, 처음에 개발자들이 많이 당황할수 있다. 

나는 안드로이드 C2DM 할때보다 아이폰 APNS가 조금 어렵게 작업하게 되었다. 

APNS 의 구동 방식은 아래의 그림과 같다. 



1) 개발을 위한 Certification 등록 
기본 구조는
1. 당신의 SSL certificate 을 이용한 APNS 접속

2. 아래 그림의 사이클


  
3.  각각의 메세지의 구성

4. APNS 의 disconnet 이다.
 

APNS 에 등록하기 전에 먼저 해야 할 작업이 몇가지들이 있다.
순서대로만 하면 아무 무리 없이 작업에 성공할수 있을것이다.

개발에 앞서 APP ids 에 개발할수 있는 provisiong 을 다운 받아야 한다. 

  
오른쪽에 오랜지 색으로 나올때 configure 클릭한다.

Development Push SSL certificate 을 생성한다. 
아래 Production Push SSL certificate 는 구지 생성하지 않는다. (여기서 사용은 안합니다.. )
***** 아래의 인증서는 가장 최신것을 받는게 좋다. 기기의 변경 혹은 맥북의 변경이나 운영체제 업데이트를 한 뒤에는
반드시 삭제하고 다시 받기를 권면한다.
  ******



자 이제 certificate 을 다운 받았다면 더블 클릭하여 개발에 착수한다. 

크게 개발의 라이브러리는 


1. APNS-PHP

2. Easy APNS

3. PHP-APNS


이렇다.
1. APNS-PHP

기기등록과 푸시방법 통합버전

0. keychain -> 인증서 지원 ->  yspark_인증기관에서 인증서 요청

1. https://developer.apple.com 로그인

2. certificates -> Action update /  padding 처리걸어놈

3. WWDR click here to download now /  다운로드

4. certificates -> Action update /  리플레쉬 하면 download 할수 있음

5. devices 기기등록

6. APP IDs 새로이 등록(푸시포함)

    NEW ID 등록 또는 configure 클릭하여 기존(kr.antas.point5 수정)

     여기서 push을 등록할땐 development 와 production 키가 따로 따로 있음을 주의한다.

     0번에서 받은 인증키을 첨부파일로 넣는다

7. 6번에서 등록한 push certification key 다운로드 받아 클릭한다

8. procisioning / 기존 provisioning profile 필요가 없다면 삭제 

   NEW 등록 하여6번에 사용할 APPID 을 클릭하여 준다.

9. 8번 다운로드를 하면 XCODE 오거나이져에 등록되며, 개발환경을 만들어 준다. 

10. 서버단에 pem 파을을 올려야 하는데. 키체인에서 6번에서 받은 push certification 키 - 2개 보내기 - (Apple Development IOS Push Servicesyspark key 따로 따로 각각 오른쪽 마우스를 눌러 보내기를 한다. 

3. certification .cer 파일 - pem 파일로 변경
조금 복잡할수도 있지만, 셋팅이 거의 다 왔다.
cer 파일을 pem 파일로 등록해야 PHP 에서 인증을 완료 할수 있다.
어려워 하지말며, 그냥 따라 치기만 하면 됩니다.

*각각 하나하나 클릭해서 보내기를 해야함
키체인에서 그림과 오륹쪽 마우스를 눌러 보내기를 합니다.
development 와 그 아래 key 만 보내면 됩니다.

terminal 을 이용하여 PEM 포멧형식으로 바꾸는데요.

openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
입력후 암호

openssl pkcs12
-nocerts -out apns-dev-key.pem -in apns-dev-key.p12
입력후 암호

passphrease를 개인키에서 제거하기 위해 다음의 명령을 수행합니다.
openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem

마지막으로 key파일과 cert파일을 통합합니다. 결과적으로 이 파일을 이용하여 APNS에 접근하게 됩니다.
cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem

실서비스용 PEM파일도 위와 같은 과정을 거쳐 apns-production.pem 파일로 생성해 주시면 됩니다.
이렇게 하나하나 실행후 암호 를 하면 에러 없이 파일들이 만들어 진다. 

혹시 에러가 날경우는 다시 키를 보내기하여 터미널 첫단계부터 해보자

11. 만들어진 apns-dev.pem 파일을 서버단에 넣는다.

12. 푸시를 보낼수 있는 php 파일로 소스는 아래와 같다. 

<?php

$deviceToken = "d33c32bfde342cf35e0c2ebe77295e2250fbbd2dafcdcfcffxxxxxxxx";

$alert = "Point5 test";

$badge = 1;

#$sound = "default";

$sound = "alarm5.caf";

$user = "user";

$custom_key = "custom";

$custom_value = "custom data";


$certPass = ''; 

$certFile = 'apns-dev.pem';

$deviceToken = str_replace(" ","",$deviceToken);

$deviceToken = pack('H*', $deviceToken);


$tmp = array();

if($alert) $tmp['alert'] = $alert;

if($badge) $tmp['badge'] = $badge;

if($sound) $tmp['sound'] = $sound;

if($sound) $tmp['user'] = $user;


$body['aps'] = $tmp;

$body[$custom_key = $custom_value];


$ctx = stream_context_create();

stream_context_set_option($ctx, 'ssl', 'local_cert', $certFile);

stream_context_set_option($ctx, 'ssl', 'passphrase', $certPass);


$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);

//$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);

if(!$fp) {

print "Connection failed $err $errstr\n";

return;

}

$payload = json_encode($body);

$msg = chr(0) . chr(0) . chr(32) . $deviceToken . chr(0) . chr(strlen($payload)) . $payload;


fwrite($fp, $msg);

fclose($fp);


echo "Send Notification!";

?>


13. XCODE에 어플에 필요한 소스를 넣어줘야 한다. 

3. Client side (iPhone / iPad / iPod Touch)


푸쉬 통보 서비스에 자신을 등록시킴

- registerForRemoteNotificationTypes : 푸시 통보 서비스를 사용할 있게 어플리케이션을 등록함

- unregisterForRemoteNotifications : 푸시 통보 서비스를 이상 사용하지 않을

- enabledRemoteNotificationTypes  : 아이폰 OS 사용자에게 푸시 통보를 알리는 가지 방법을 켜거나 있는 플래그






- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

    // Override point for customization after application launch.

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {

        self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil] autorelease];

    } else {

        self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil] autorelease];

    }

    self.window.rootViewController = self.viewController;

    [self.window makeKeyAndVisible];

    

    // 뱃지 값을 0으로 초기화시킨다. 어플리케이션이 실행될 뱃지 값을 초기화 하는 것이 좋다 (but 상황에 따라 다름)

    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];

    

    // 푸시 통보 서비스에 자신을 등록시킴

    // 성공이면 didRegisterForRemoteNotificationsWithDeviceToken 호출됨

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:

     UIRemoteNotificationTypeAlert |

     UIRemoteNotificationTypeBadge |

     UIRemoteNotificationTypeSound];

    

    return YES;

}






     

델리게이트






// registerForRemoteNotificationTypes 결과 성공적으로 등록되었을 호출됨

// 여기서 받은 토큰 값을 프로바이더에게 전달하는 것은 어플리케이션 몫임

// TCP연결을 따로 맺어 전달하거나 서버에 서비스로 등록할 있음

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

    //

    NSMutableString *deviceId = [NSMutableString string];

    const unsigned char *ptr = (const unsigned char *)[deviceToken bytes];

    

    for (int i=0; i<32; i++) {

        [deviceId appendFormat:@"%02x", ptr[i]];

    }

    NSLog(@"APNS Device Token: %@", deviceId);

    // TODO :

    // 여기서 토큰을 프로바이더 서버로 전달하면

}









// registerForRemoteNotificationTypes 결과 실패했을 호출됨

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {

    NSLog(@"%@", error);

}










// 어플리케이션이 실행중일 노티피케이션을 받았을 호출됨

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

    NSString *string = [NSString stringWithFormat:@"%@", userInfo]; 

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil 

                                                    message:string delegate:nil

                                          cancelButtonTitle:@"OK"

                                          otherButtonTitles:nil]; 

    [alert show]; 

    [alert release]; 

}









// 어플리케이션이 실행중이 아닐 노티를 받아 View 버튼을 누른 경우 호출되며 어플이 시작됨

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// 위의 코드 참고





참고사이트

http://artyst.egloos.com/2650529

http://artyst.egloos.com/2652130

소스(서버, 클라이언트, IOS)

http://code.google.com/p/apns-php/


2. Easy APNS

회사에서는 2번 APNS-PHP 을
저는 여기서 1번의 Easy APNS 을 사용해 보려 합니다.
http://www.easyapns.com/

(여기에 들어 가면 아이폰-PHP-MYSQL 의 모든 소스를 제공하며, 또한 동영상도 제공해줍니다.)


EasyAPNs - Getting everything setup from Raphael Caixeta on Vimeo.

PUSH 을 보내기 전에 준비사항

2) DB table - 보낼 데이터에 대해 save 와 read 하는 DB table 을 만들것입니다. 

 
manifestinteractive-easyapns-678c62d.zip 
총 3가지인데요.
 
apns_devices에서 trigger 는 삭제하여 사용하셔야 합니다.
 apns_device_history 

 CREATE TABLE `apns_device_history` (
  `pid` int(9) unsigned NOT NULL auto_increment,  `appname` varchar(255) NOT NULL,  `appversion` varchar(25) default NULL,  `deviceuid` char(40) NOT NULL,  `devicetoken` char(64) NOT NULL,  `devicename` varchar(255) NOT NULL,  `devicemodel` varchar(100) NOT NULL,  `deviceversion` varchar(25) NOT NULL,  `pushbadge` enum('disabled','enabled') default 'disabled',  `pushalert` enum('disabled','enabled') default 'disabled',  `pushsound` enum('disabled','enabled') default 'disabled',  `development` enum('production','sandbox') character set latin1 NOT NULL default 'production',  `status` enum('active','uninstalled') NOT NULL default 'active',  `archived` datetime NOT NULL,  PRIMARY KEY  (`pid`),  KEY `devicetoken` (`devicetoken`),  KEY `devicename` (`devicename`),  KEY `devicemodel` (`devicemodel`),  KEY `deviceversion` (`deviceversion`),  KEY `pushbadge` (`pushbadge`),  KEY `pushalert` (`pushalert`),  KEY `pushsound` (`pushsound`),  KEY `development` (`development`),  KEY `status` (`status`),  KEY `appname` (`appname`),  KEY `appversion` (`appversion`),  KEY `deviceuid` (`deviceuid`),  KEY `archived` (`archived`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Store unique device history';


 apns_devices

CREATE TABLE `apns_devices` (  `pid` int(9) unsigned NOT NULL auto_increment,  `appname` varchar(255) NOT NULL,  `appversion` varchar(25) default NULL,  `deviceuid` char(40) NOT NULL,  `devicetoken` char(64) NOT NULL,  `devicename` varchar(255) NOT NULL,  `devicemodel` varchar(100) NOT NULL,  `deviceversion` varchar(25) NOT NULL,  `pushbadge` enum('disabled','enabled') default 'disabled',  `pushalert` enum('disabled','enabled') default 'disabled',  `pushsound` enum('disabled','enabled') default 'disabled',  `development` enum('production','sandbox') character set latin1 NOT NULL default 'production',  `status` enum('active','uninstalled') NOT NULL default 'active',  `created` datetime NOT NULL,  `modified` timestamp NOT NULL default '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP,  PRIMARY KEY  (`pid`),  UNIQUE KEY `appname` (`appname`,`appversion`,`deviceuid`),  KEY `devicetoken` (`devicetoken`),  KEY `devicename` (`devicename`),  KEY `devicemodel` (`devicemodel`),  KEY `deviceversion` (`deviceversion`),  KEY `pushbadge` (`pushbadge`),  KEY `pushalert` (`pushalert`),  KEY `pushsound` (`pushsound`),  KEY `development` (`development`),  KEY `status` (`status`),  KEY `created` (`created`),  KEY `modified` (`modified`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Store unique devices';

아래 부분은 삭제하여 query 에 적용하시길 바랍니다.DELIMITER ;;CREATE TRIGGER `Archive` BEFORE UPDATE ON `apns_devices` FOR EACH ROW INSERT INTO `apns_device_history` VALUES ( NULL, OLD.`appname`, OLD.`appversion`, OLD.`deviceuid`, OLD.`devicetoken`, OLD.`devicename`, OLD.`devicemodel`, OLD.`deviceversion`, OLD.`pushbadge`, OLD.`pushalert`, OLD.`pushsound`, OLD.`development`, OLD.`status`, NOW());; 
DELIMITER ;
 


apns_messages
CREATE TABLE `apns_messages` (  `pid` int(9) unsigned NOT NULL auto_increment,  `fk_device` int(9) unsigned NOT NULL,  `message` varchar(255) NOT NULL,  `delivery` datetime NOT NULL,  `status` enum('queued','delivered','failed') character set latin1 NOT NULL default 'queued',  `created` datetime NOT NULL,  `modified` timestamp NOT NULL default '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP,  PRIMARY KEY  (`pid`),  KEY `fk_device` (`fk_device`),  KEY `status` (`status`),  KEY `created` (`created`),  KEY `modified` (`modified`),  KEY `message` (`message`),  KEY `delivery` (`delivery`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Messages to push to APNS';

PHP 파일 + myslq table + apple delegate
manifestinteractive-easyapns-678c62d.zip 
apple delegate
/** * This is what you need to add to your applicationDidFinishLaunching */- (void)applicationDidFinishLaunching:(UIApplication *)application{ // Add registration for remote notifications [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; // Clear application badge when app launches application.applicationIconBadgeNumber = 0;}/* * -------------------------------------------------------------------------------------------------------------- * 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]; NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSLog(@"Register URL: %@", url); NSLog(@"Return Data: %@", returnData); #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 * -------------------------------------------------------------------------------------------------------------- */


apple delegate을 하게 되면 LOG 가 정상적으로 찍히게 됩니다.
그러나 저는 LOG에
c9d4c07c fbbc26d6 ef87a44d 53e16983 1096a5d5 fd825475 56659ddd f715defcc9d4c07c fbbc26d6 ef87a44d 53e16983 1096a5d5 fd825475 56659ddd f715defcc9d4c07c fbbc26d6 ef87a44d 53e16983 1096a5d5 fd825475 56659ddd f715defc
....
...

이러한 것이 찍히며 이상하게 생각이 들었지요.


저는 웹 호스팅을 CAFE24을 이용하는데요.

Host '118.219.234.98' is not allowed to connect to this MySQL server in ...


나의 서비스관리 - 서비스 사용현황 - MySQL 외부 IP 접근설정에IP 등록을 하셔야 합니다.

또한 저 처럼 cafe24을 이용하지 않으시고 개인적으로 서버구축이나 다른 웹호스팅을 사용하고 계신다면
localhost로는 접속이 가능하고 IP로는 접속이 불가능한 이유는 접속가능한 IP로 등록이 되어 있지 않기 때문입니다.

select * from mysql.user

로 보시면 localhost는 보이나 IP는 보이지 않을것입니다.

mysql> grant all privileges on db명.* to 사용자계정@'IP주소'
identified by '비밀번호' with grant option;
mysql> grant reload,process on *.* to admin@localhost;
mysql> FLUSH PRIVILEGES;
위의 명령어로 접속가능한 IP로 등록해 주면됩니다.


4) 이제 실행입니다.
 
위에 올려놓았던 파일에 수정되는 소스만 올려드립니다.
apns.php
include("classes/class_APNS.php");include("classes/class_DbConnect.php");// CREATE DATABASE OBJECT ( MAKE SURE TO CHANGE LOGIN INFO )//$db = new DbConnect('localhost', 'apnsuser', 'apnspassword', 'apnsdb');$db = new DbConnect();$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); 

class_DbConnect.php
function __construct() { $this->DB_HOST = 'point5xxxxxx'; $this->DB_USERNAME = 'point5xxxxxx'; $this->DB_PASSWORD = 'point5xxxxxx'; $this->DB_DATABASE = 'point5xxxxxx'; } 
이렇게 자신의 계정으로 변경하게 됩니다.  

samples.php 
include("classes/class_APNS.php");include("classes/class_DbConnect.php");// CREATE DATABASE OBJECT ( MAKE SURE TO CHANGE LOGIN INFO )$db = new DbConnect('point5xxxxxxx', 'point5xxxxxxx', 'point5xxxxxxx', 'point5xxxxxxx');//$db = new DbConnect();$db->show_errors();
 
// APPLE APNS EXAMPLE 1 ,2 ,3, ... 자신이 원하는 것만 빼고 주석처리
 
5) Error 총정리
제가 하면서 에러났던 것들 로그남겨 드립니다.

1) triggererror -> file: class_apns.php - 
위에서 DB 생성할때 trigger 을 제거하여 create 하면 됩니다.
이 부분은 처음엔 잘되는데, 디비의 손상이 생기는지 자꾸 이러한 에러가 나네요..

Notice
: This user does not exist in the database. Message will not be delivered. 1) APNS::queueMessage -> File: apns-sendtext.php (line 64) 2) APNS::_triggerError -> File: class_APNS.php (line 736) in /home/hosting_users/point5web/www/apns-push/classes/class_APNS.php on line 557 

사용중인 hosting 은 카페24입니다.
---------------------------------------------------

안녕하세요. 카페24 호스팅입니다.

 

고객님이 사용하시는 서비스는 procedure/function/trigger를 지원하지 않습니다.

 

현재 트리거 기능을 사용하시려면 단독웹에서 php5 를 선택하시거나, 가상서버 등의 독립 서버를 이용하셔야 합니다.

단, procedure/function은 innodb 호스팅에서 지원하고 있습니다.

http://www.cafe24.com/?controller=product_special&method=innodb

 

감사합니다.
--------------------------------------------------- 

그래서 trigger 을 제거 하는 방법을 연구중에 있습니다.
또한

2. APNS-PHP

easy pans 블로그 설명

http://itzone.tistory.com/434


apns 블로그 설명

http://fra3il.tistory.com/47


iPhone Push Notification(APNS) PHP에서 보내는 방법

http://theeye.pe.kr/511

http://artyst.egloos.com/2652130

http://theeye.pe.kr/entry/iPhone-Push-NotificationAPNS%EB%A5%BC-PHP%EC%97%90%EC%84%9C-%EB%B3%B4%EB%82%B4%EB%8A%94-%EB%B0%A9%EB%B2%95

아이폰 기기테스트 하기

http://blog.daum.net/komate/168


3. PHP-APNS
이런 방법으로 우회 해야 할거 같네요. 

 
단독웹은 비용이 대략 10만원에서 20만원사이에 한다.

2) APNS::queueMessage -> File: samples.php -> DB 접근을 못했을때 입니다. 이것도 역시 위에서 말씀

드렸다 시피, 접근 IP을 확인해보시도록 하세요..