iPhoneの最近のブログ記事

iPhoneのインスタントアラートサービス (APNS)をiPhoneアプリケーション開発に適用する方法を説明します。


やることは4つです。

  1. まずはPushNotificationサービス機能をONにしたProvisioningファイルを取得する必要がある。

    • iPhone Developer Connection PortalにアクセスしてApp IDsタブを選択
    • App IDはワイルドカード(*)は使用してはいけない。ワイルドカードを使用したらPush Serviceを使用することができない。例(私のApp ID) 
      AB123346CD.com.serverdensity.iphone 
       
    • Submitを押して保存後、Enable for Apple Push Notification Serviceを選択してからDevelopment Push SSL CertificateのConfigureをクリックする
    • Keychain Access部分は説明通り辿っていけばOK。その後signed authorityをportalにアップロードしてcertificateファイル(*.cer)をダウンロードしてくる
    • certificateファイルをダブルクリックしてKeychain Accessにインポートする
    •        
    • Keychain AccessのCertificatesカテゴリを選択して、"Apple Development Push Services"を見つける
    •        
    • "Apple Development Push Services" を右クリックして Export "Apple Development Push Services ID123″を選択し、"apns-dev-cert.p12"と名前をつけて保存
    •        
    • その真下にある"Private Key"も同様で"apns-dev-key.p12"を名前をつけて保存
    •        
    • これらのファイルを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
      
    •        
    • サーバーがAPNSにアクセスするときにPEMファイルが必要なので、keyとcertファイルを合わせないて、apns-dev.pemファイルとして保存する

      cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem

  2. iphoneアプリ側でUIApplicationで registerForRemoteNotificationTypes:を呼ぶ

  3. - (void)applicationDidFinishLaunching:(UIApplication *)application {    
            
    <必要な処理。。>
     //push notification [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; application.applicationIconBadgeNumber = 0; }
  4. iphoneアプリ側でUIApplicationDelegateの application:didRegisterForRemoteNotificationsWithDeviceToken: メソッドをインプリメントしてiPhone端末に通知するために必要な device tokenを取得する。

  5. - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
    	
    	#if !TARGET_IPHONE_SIMULATOR
    
    // Get the users Device Model, Display Name, Unique ID, Token & Version Number
    	UIDevice *dev = [UIDevice currentDevice];
    	NSString *deviceUuid = dev.uniqueIdentifier;
    	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: @""];
    	NSLog(@"deviceToken: %@", deviceToken);
    	#endif
    }
    
  6. 取得したdevice tokenをサーバー側に送信。device tokenを保管(DBなど)する。サーバー側からiPhone端末に通知する時にdevice tokenを使って通知する。
    <ソースコードは近日公開>


注意書き:
アプリを起動した時に下記のようなエラーメッセージがコンソールに出て、DeviceTokenを取得できない人たちが出てくるでしょう。
"Error Domain=NSCocoaErrorDomain Code=3000 UserInfo=0x113e80 "no valid 'aps-environment' entitlement string found for application"

これはビルドに使用したProvisioning ProfileがPush Notification Serviceの使用が
許可されてないからです。
まずは、プロジェクトのプロパティを開き
Code Signing Identityが先程作成したPush Notification ServiceがONになっている
Profileのを確認。一度Clean All Targetsを選択して、Buildし直してみてください。
これでも同じエラーが出るようでしたら、Provisioning Profile(*.mobileprovision)ファイルを
App IDのApple Push Notification serviceをEnableに設定する前にダウンロードした可能性が高いです。
もう一度、Provisioning Profile(*.mobileprovision)ファイルを
ダウンロードしてXcodeのOrganizerを使って適用したらいいでしょう。
あと、Organizerで古いProvisioning Profileは削除した方がいいです。
時々古いファイルを読み込んでしまう時があります。



私のオススメiPhone開発本
iTunes Connectを使ってDistribution用にBuildしてZIP圧縮したファイルをアップロードすると、
"The binary you uploaded was invalid. The signature was invalid, or it was not signed with an Apple submission certificate."というエラーが起きていた。数時間いろいろ同じ体験をしているユーザーの書き込みを見ていろいろと試してみた。私の環境では最後の4番目の方法が上手くファイルをアップロードできるようになりました。

1。codesign -vvvv MyAppName.app をして正しく下記が出力されるか
MyAppName.app: valid on disk
MyAppName.app: satisfies its Designated Requirement
2。MyAppName.app を右クリックして「パッケージの内容を表示」を選択して中身に壊れているファイルがないかをチェック
*注意:ZIP圧縮をかけてからやってください。内容を表示したらファイルを壊す可能性があるので、まずはZIP圧縮してからチェックするように

3。info.plistのBundle identifierでは
com.mycompany.${PRODUCT_NAME:identifier}
のままではいけません。
com.mycompany.AppName
という感じに直す。

4。.xcodeproj パッケージの中のproject.pbxprojを開いて Distribution 部分のところを確認する
84D2ED8E0E5B857A00CAA465 /* Distribution */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = iphoneos2.0;
};
name = Distribution;
};
84D2ED8F0E5B857A00CAA465 /* Distribution */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "iPhone Distribution: My Company Name Ltd.";
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = ThisApp_Prefix.pch;
INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = ThisApp;
PROVISIONING_PROFILE = "00D072E0-3459-4AFF-911E-B31D325E7375";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "B260C653-9A45-372C-A472-31F1531EEA44";
};
name = Distribution;
};

2つ目の"PROVISIONING_PROFILE"を消してファイルを保存。プロジェクトクリーンして再ビルドしたらOK.
参考:http://discussions.apple.com/message.jspa?messageID=9167082#9167082

nginxではpsuedo streamingという途中再生が可能になる機能に対応している。
たとえば、ファイル名の後に ?start=60 を付けたら最初から1分後からの動画をリクエストできるようになっている。
これをiPhoneでも試してみようと思ったが、少し工夫が必要だったのでここに記載する。
iPhoneで再生可能なのはmp4ファイルで、videoがh.264、audioがaacだ。
 
Ngix&mp4ストリーミングモジュールインストール方法
cd /usr/local/src/
wget http://www.nginx.eu/download/sources/nginx-0.7.9.tar.gz
tar zxvf nginx-0.7.9.tar.gz

 ②

cd /usr/local/src/
svn export http://h264.code-shop.com/svn/h264/tags/mod_h264_streaming-2.1rc2/nginx nginx_http_h264_streaming
svn export --force http://h264.code-shop.com/svn/h264/tags/mod_h264_streaming-2.1rc2/mp4split nginx_http_h264_streaming

③ 

cd /usr/local/src/nginx-0.7.9
./configure --add-module=/usr/local/src/nginx_http_h264_streaming --sbin-path=/usr/local/sbin --with-debug
make
sudo make install

 vi /usr/local/nginx/conf/nginx.conf

下記を追加(43行目ぐらい):

location ~ \.mp4$ {
  mp4;
}
⑤起動
sudo /usr/local/sbin/nginx

-------------------------------------------------------------------------------------------------------

モジュールのSVN(iphone再生対応しているブランチ):

http://h264.code-shop.com/svn/h264/tags/mod_h264_streaming-2.1rc2/nginx

http://h264.code-shop.com/svn/h264/tags/mod_h264_streaming-2.1rc2/mp4split

 

参照:

http://h264.code-shop.com/trac/wiki/Mod-H264-Streaming-Nginx-Version2 - Nginxインスト方法

(ここに記載されているmod_h264_streamingはiPhone再生に対応していない)

http://h264.code-shop.com/trac/discussion/1/18 - iPhone range requestの件

http://h264.code-shop.com/trac/wiki/ReleaseNotes-Version2 iPhone range requestに対応しているバージョン