3

こんにちは、かなり単純なことをしようとしています。APNS を使用してデータを送信し、データベースからトークンを取得するココア アプリケーションを作成しました。すべてがセットアップされ、完璧に動作しています。

ここで、APNS フィードバック サーバーを確認し、データベースから受信したトークンをすべて削除します。PHP、JavaScript などで数十の例を見つけましたが、Objective C では何も見つかりませんでした。Apple のプログラミング ガイドを読みましたが、その方法がわかりません。

APNS フィードバックへの接続を確立していますが、データの読み取り方法がわかりません。私はココアに慣れていないので、詳しく説明してください:)

これは、フィードバック サーバーに接続する方法です。別のホストを使用するだけで、送信時に接続する方法と同じです。

- (void)connectToFeedBackServer
{
    if(self.certificate == nil)
    {
    return;
}

    NSString *feedBackHost = @"feedback.push.apple.com";
    const char *cHost = [feedBackHost UTF8String];
    NSLog(@"The size of cHost is: %lu", strlen(cHost));


    NSLog(@"Host is: %s", cHost);
// Define result variable.
OSStatus result;

// Establish connection to server.
PeerSpec peer;
result = MakeServerConnection(cHost, 2196, &socket, &peer);
    //NSLog(@"MakeServerConnection(): %d", result);

// Create new SSL context.
result = SSLNewContext(false, &context); //NSLog(@"SSLNewContext(): %d", result);

// Set callback functions for SSL context.
result = SSLSetIOFuncs(context, SocketRead, SocketWrite);
    // NSLog(@"SSLSetIOFuncs(): %d", result);

// Set SSL context connection.
result = SSLSetConnection(context, socket);
    // NSLog(@"SSLSetConnection(): %d", result);

// Set server domain name.
//result = SSLSetPeerDomainName(context, cHost, sizeof(cHost));
    NSLog(@"SSLSetPeerDomainName(): %d", result);
    result = SSLSetPeerDomainName(context, cHost, strlen(cHost));


    result = SecIdentityCopyCertificate(_theIdentity, &(certificate));

// Set client certificate.
CFArrayRef certificates = CFArrayCreate(NULL, (const void **)&_theIdentity, 1, NULL);
result = SSLSetCertificate(context, certificates);// NSLog(@"SSLSetCertificate(): %d", result);
CFRelease(certificates);

// Perform SSL handshake.
do 
    {
    result = SSLHandshake(context); NSLog(@"SSLHandshake(): %d", result);
} while(result == errSSLWouldBlock);
}

そして、データを読み取って、受信したトークンを配列に保存する方法

- (NSMutableArray *)CheckFeedBackServer
{
    char feedback[38];
    size_t feedBackSize = sizeof(feedback);
    size_t processed = 0;

    NSMutableData *feedbackData = [[NSMutableData alloc]init];
    NSString *token = [[NSString alloc]init];
    NSMutableArray *tokenArray = [[NSMutableArray alloc]init];

    [self connectToFeedBackServer];
    while ([self getSSLContext])
    {
        int bytesLength = SSLRead([self getSSLContext], &feedback, feedBackSize, &processed);

        [feedbackData appendBytes:feedback length:bytesLength];

        while ([feedbackData length] > 38)
        {
            NSData *deviceToken = [NSData dataWithBytes:[feedbackData bytes] + 6 length:32];

            token = [self deviceTokenToString:deviceToken];

            [tokenArray addObject:token];

            [feedbackData replaceBytesInRange: NSMakeRange(0, 38) withBytes: "" length: 0];
        }
    }
    return tokenArray;
}

- (NSString *)deviceTokenToString: (NSData *)deviceToken;
{
    NSString *tmpToken = [NSString stringWithFormat:@"%@", deviceToken];
    NSUInteger loc_begin = [tmpToken rangeOfString: @"<"].location+1;
    NSUInteger loc_end = [tmpToken rangeOfString: @">"].location-1;
    return [tmpToken substringWithRange: NSMakeRange(loc_begin, loc_end)];
}
4

1 に答える 1

2

誰かが似たようなことをする必要がある場合、私はこのように問題を解決しました。

Apples ioSock クラスを使用し、キーチェーンを呼び出してコードに証明書を設定しました

まず、このコードを使用してフィードバック サーバーに接続します

- (void)connectToFeedBackServer
{
    if(self.certificate == nil)
    {
    return;
}

    // Get the global variable feedbackHost and make it to a char
    const char *cHost = [feedbackHost UTF8String];
    NSLog(@"The size of cHost is: %lu", strlen(cHost));

    NSLog(@"Host is: %s", cHost);
    // Define result variable.
    OSStatus result;

    // Establish connection to server.
    PeerSpec peer;
    result = MakeServerConnection(cHost, 2196, &socket, &peer); 

    // Create new SSL context.
    result = SSLNewContext(false, &context); 

    // Set callback functions for SSL context.
    result = SSLSetIOFuncs(context, SocketRead, SocketWrite);

    // Set SSL context connection.
    result = SSLSetConnection(context, socket);

    // Set server domain name.
    result = SSLSetPeerDomainName(context, cHost, strlen(cHost));

    result = SecIdentityCopyCertificate(_theIdentity, &(certificate));

    // Set client certificate.
    CFArrayRef certificates = CFArrayCreate(NULL, (const void **)&_theIdentity, 1, NULL);
    result = SSLSetCertificate(context, certificates);
    CFRelease(certificates);

    do
    {
        result = SSLHandshake(context); NSLog(@"SSLHandshake(): %d", result);
    } while(result == errSSLWouldBlock);

}

次に、フィードバック データを読み取り、次のようにトークンを配列に追加します。

- (NSMutableArray *)CheckFeedBackServer
{
    OSStatus result;

    NSMutableArray *feedbackTokens = [[NSMutableArray alloc]init];

    // Retrieve message from SSL.
    size_t processed = 0;
    char buffer[38];
    do
    {
        // Fetch the next item
        result = SSLRead(context, buffer, 38, &processed);
        if (result) break;

        char *b = buffer;

        // Recover Device ID
        NSMutableString *deviceID = [NSMutableString string];
        b += 6;
        for (int i = 0; i < 32; i++)
        {
            [deviceID appendFormat:@"%02x", (unsigned char)b[i]];
        }
        [feedbackTokens addObject:deviceID];

    } while (processed > 0);

    return feedbackTokens;
}
于 2013-03-05T20:14:26.450 に答える