iRSSの日記

はてなダイアリーiRSSの日記の続き

Newsstandメモ

自分用のメモ。
サンプルソース等は、後ほど、アップする予定

参考にしたいページ

WWDC2011 video Building Newsstand Apps

https://developer.apple.com/videos/wwdc/2011/?id=504
ビデオ60分ですが、必見。NewsstandAppにする方法、ダウンロード方法と管理の仕組み、NKLiblaryとNKIssieの関係
スライドもある。残念なのは、ソースコードがないこと。
ビデオ内でデモ画面に移るコードは参考になる。
バックグラウンドでダウンロードができているデモや、ダウンロード中にアプリがkillされても、再起動すると、resumeしてくれるところとかが、デモで紹介されている。

Push Nortification

最新コンテンツをダウンロードするために、Pushを送ってバックグラウンドで起動させるは、APNSのプッシュで

{
‘aps’:{
         ‘content-available’:1
     }
}

を送信すればよい。とドキュメントには書いてある。

iOSクライアント側では
UIRemoteNotificationTypeNewsstandContentAvailability
に反応できるように、しておく。


Net::APNS::Persistent - Send Apple APNS notifications over a persistent connection - metacpan.org
を使って'content-available' => 1,としたが、これだと、1がうまく届かなかった。どうも文字として送られている模様(想像)

use strict;
use warnings;
use Net::APNS::Persistent;

my $devicetoken_hex = 'fa927e5ff2ed456dd197dba.....';

my $apns = Net::APNS::Persistent->new({
                sandbox => 1,
                cert    => 'apns-dev.pem',
                key     => 'apns-dev-key-noenc.pem',
                passwd  => 'mtlmtl',
                });

$apns->queue_notification(
            $devicetoken_hex,
            { 
              aps => {
                  'content-available' => 1,
              },
            });

$apns->send_queue;

$apns->disconnect;

上記ソースでは、クライアント側が反応してくれない。
ソースみればよいのだけど、時間がなかったので,
PHPでうごくのがわかったので、そちらでためしてうまくいった。

<?php

// Put your device token here (without spaces):
$deviceToken = 'd6e00f775a60523eb1dbd97e7fef88ea8283d87e4000e910456e1f57b870774e'; #4

/ Put your private key's passphrase here:
$passphrase = 'hoge';

// Put your alert message here:
$message = 'haro-';

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client(
    'ssl://gateway.sandbox.push.apple.com:2195', $err,
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
    exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
    'alert' => $message,
    'sound' => 'default',
    'content-available' => 1 
    );  

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
    
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
    
if (!$result)
    echo 'Message not delivered' . PHP_EOL;
else
    echo 'Message successfully delivered' . PHP_EOL;

// Close the connection to the server
fclose($fp);

通常は24時間に1回までなのだが、テストのときはそうもいってられないので

[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NKDontThrottleNewsstandContentNotifications"];

をアプリ起動時に呼び出しておく。
これで、Pushを送るたびに反応してくれる。


NKIssueのダウンロードの再開

downloadingAssetsの配列に含まれる、NKAssetDownloadにたいしてdownloadWithDelegateをおくる。
これで、ダウンロードが途中でも取得再開してくれる。

    //Newsstandによるダウンロードの再取得。アプリが終了していた場合に再開させるために使用する
    for (NKAssetDownload *assetDownload in [[NKLibrary sharedLibrary] downloadingAssets] ){
        JLNDownloadWatcher *dlw = [[JLNDownloadWatcher alloc] init];
        dlw.issue = assetDownload.issue;
        NSURLConnection *urlc = [assetDownload downloadWithDelegate:dlw];    
#ifdef DEBUG
        NSLog (@"issue.name:%@ urlc:%@",assetDownload.issue.name,urlc);
#endif
    }

NKIssueContentStatus

NKIssueContentStatusNoneになるのは、contentURL内にファイルが一つもないとき。逆に一つでもあるとNKIssueContentStatusAvailableになる。
Downloadはできたけど、Zip解凍に失敗して、その残骸がcontentURL内に残っていても、NKIssueContentStatusAvailableになるので注意。

課金について

アプリ内課金は最低一つは提示する必要があるが、FreeSuscriptionもできたので、無料アプリでも大丈夫。
課金の仕組みとNewsstandのNKLiblaryは特に連携はしていない。購入済みかどうかの確認はStoreKitでできるというだけ。コンテンツサーバーは自分で用意する必要がある。