已上架app 推播處理方式
Step 1: 進入 iOS Developer Center, 點 Cerfificates
網址:https://developer.apple.com/membercenter/index.action



Step 2: 按下面的步驟可以產生 CSR, 產生好後按 "Continue"

Step 3: 上傳 CSR 檔案,並按下 Generate

Step 3: 下載certificate

說明: 這個 certificates 分 development 和 product, develop 的好像3個月會過期,要重新 generate 並 download 一次.
Q: Step 3: 上傳 CSR 檔案,並按下 Generate
development跟product需要從分別不同的CSR嗎?還是同一個CSR就可以了 A: 還是同一個CSR就可以了 .
接下來的步驟,只能在 Mac 上執行.接棒給Mac.
(其實: 從頭到尾通通在 Mac 上做就ok了.)
Step 4: 進入 keychain 匯出 Push Services key 為 .p12 的檔案


輸入 password

Step 9: 產生 pem 檔案:
openssl pkcs12 -clcerts -nokeys -out cert.pem -in ios_push_cert.p12
openssl pkcs12 -nocerts -out key.pem -in ios_push_cert.p12
openssl rsa -in key.pem -out key.unencrypted.pem
cat cert.pem key.unencrypted.pem > ck.pem
production指令範例:
openssl pkcs12 -clcerts -nokeys -out cert_production.pem -in ios_push_cert_production.p12
openssl pkcs12 -nocerts -out key_production.pem -in ios_push_cert_production.p12
openssl rsa -in key_production.pem -out key.unencrypted_production.pem
cat cert_production.pem key.unencrypted_production.pem > ck_production.pem
測試 sandbox push server 是否可以被連到:
telnet gateway.sandbox.push.apple.com 2195
測試 sandbox push server 是否可以使用 SSL 憑證連到:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert pushtestcert.pem -key pushtestkey.pem
swift 取得taken id 方式
以下的程式 單純只是為取TokenID
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if application.respondsToSelector("registerUserNotificationSettings:") {
if #available(iOS 8.0, *) {
let types:UIUserNotificationType = ([.Alert, .Sound, .Badge])
let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
application.registerForRemoteNotificationTypes([.Alert, .Sound, .Badge])
}
}
else {
// Register for Push Notifications before iOS 8
application.registerForRemoteNotificationTypes([.Alert, .Sound, .Badge])
}
return true
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
application.registerForRemoteNotifications()
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
NSLog("Token is : %@",deviceToken)
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
直接複製貼上即可
php 推播程式
<?php
$deviceToken = 'e2dc4b3a39f022679c51e82ced717145c51eaed48b8df879f966a5b6d8639195';//没有空格
$body = array("aps" => array("alert" => 'message', "Badge" => 2, "sound" => 'default'), 'custom_key' => '222');//推送方式,包含内容和声音
$ctx = stream_context_create();
//如果在Windows的服务器上,寻找pem路径会有问题,路径修改成这样的方法:
//$pem = dirname(__FILE__) . '/' . 'apns-dev.pem';
//linux 的服务器直接写pem的路径即可
stream_context_set_option($ctx, "ssl", "local_cert", "ck.pem");
$pass = "loverain5477";
stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);
//此处有两个服务器需要选择,如果是开发测试用,选择第二名sandbox的服务器并使用Dev的pem证书,如果是正是发布,使用Product的pem并选用正式的服务器
//$fp = stream_socket_client("ssl://gateway.push.apple.com:2195", $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
$fp = stream_socket_client("ssl://gateway.sandbox.push.apple.com:2195", $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
if (!$fp) {
echo "Failed to connect $err $errstrn";
return;
}
print"Connection OK\n";
$payload = json_encode($body);
$msg = chr(0).pack("n", 32).pack("H*", str_replace(' ', '', $deviceToken)).pack("n", strlen($payload)).$payload;
echo "sending message :".$payload."\n";
fwrite($fp, $msg);
fclose($fp);
?>
另 測試推播所用的認證,三個月就需更新一次,更新後,以上的步驟就要重新再來過,惟要注意
除了ck.pem 或 tokenid要更新外
在ios app裡面

2018 0328 補充
最最重要的,是在 .... 「憑証的使用 」
一般選擇 Automatically manage signing 是常常會發生 「Release 時的証書沒被引入」,且,如果沒有用到推播倒是沒有問題
如果要用到推播時,這裡就很重要了


另外在 build Settings -> code signing identitly 裡 debug 跟 release 各要選擇 開發時的憑証 跟 正式的憑証


請先 登入 以發表留言。