如何从目标c中的APNS反馈服务器接收数据

时间:2013-02-28 16:25:29

标签: ios objective-c cocoa apple-push-notifications feedback

您好我想要的是一些相当简单的事情。 我已经创建了一个使用APNS发送数据的cocoa应用程序,从我的数据库中获取令牌,所有内容都已设置并运行完美。

现在我想检查APNS反馈服务器并删除从我的数据库收到的任何令牌。 我已经在php,javascript等中找到了几十个例子,但在Objective C中没有。我已经阅读了苹果的编程指南,但无法弄清楚如何去做。

我正在建立与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)];
}

1 个答案:

答案 0 :(得分:2)

如果有人需要做类似的事情我就像这样解决了我的问题。

我使用的是Apples ioSock类,我通过调用keychain在我的代码中设置了证书

首先,我使用此代码连接到反馈服务器

- (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;
}