3

您好,我正在尝试做一些我认为相当简单的事情。我制作了一个可可应用程序,它使用 APNS 发送数据,从我的数据库中获取令牌,一切都已设置并运行完美。

现在我想检查 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)];
}
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 回答