iOS推送通知我做错了什么?

时间:2012-12-15 01:04:59

标签: php ios apple-push-notifications

我曾尝试多次向我的应用发送推送通知,但无济于事。我已经按照许多教程并遵循了所有步骤。我从APNS服务器收到成功的消息,但没有消息到达设备。我已经使用成功到达的开发证书测试了发送,并且我已经生成了相应的生产证书并在php脚本中使用它们。我将在下面发布我的代码。如果你看到我做错了,请告诉我。我只是不知道它是什么......

任何帮助都会非常感激。

<?php
$link=mysqli_connect('****','****','****','***');
if(mysqli_connect_errno())
{
    header('HTTP/1.1 400');
    header('Content-type: text/html');
    echo 'Connection Error: %s\n',mysqli_connect_error();
    exit;
}
echo "Connected to Database<br />";
echo "Querying Database<br />";
switch ($_REQUEST['App'])
{
    case "O2":
        $query="SELECT Token FROM O2CalculatorPushTokens";
        break;
    case "LZA":
        $query="SELECT Token FROM LZAPushTokens";
        break;
    case "MorseCode":
        $query="SELECT Token FROM MorseCodePushTokens";
        break;
    default:
        echo "Unknown App.";    
        exit;
}
$result=mysqli_query($link,$query);
echo mysqli_num_rows($result)."<br />";
if ($result==false)
{
    echo "No tokens to send to.";
}
else
{
    //Set SSL context
    $ctx = stream_context_create();
    echo "Loading SSL Certificate...<br>";
    switch($_REQUEST['App'])
    {
        case "O2":
            stream_context_set_option($ctx, 'ssl', 'local_cert', 'SSL/O2CalculatorProductionSSL.pem');
            break;
        case "LZA":
            stream_context_set_option($ctx, 'ssl', 'local_cert', 'SSL/LandingZoneAssistantProductionSSL.pem');
            break;
        case "MorseCode":
            stream_context_set_option($ctx, 'ssl', 'local_cert', 'SSL/MorseCodeProductionSSL.pem');
            break;
        default:
            exit;
    }   
    echo "Unlocking SSL Certificate...<br><br>";
    stream_context_set_option($ctx, 'ssl', 'passphrase', '****');

    //Open a connection to the APNS server
    echo "Connecting to APNS server...<br>";
    $fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
    if(!$fp) exit("Failed to connect: $err $errstr<br><br>");
    else echo "Connected to APNS!<br />";

    //Create the payload body
    echo "Creating message...<br>";
    $body['aps'] = array('alert' => $_REQUEST['PushMessageTextArea']);
    echo $body."<br>";

    //Encode the payload as JSON
    echo "Encoding message...<br>";
    $payload = json_encode($body);
    echo $payload."<br>";

    while($row=mysqli_fetch_assoc($result))
    {
        //Build the binary notification
        echo "Sending message to ".$row['Token']."<br>";
        $msg = chr(0).pack('n',32).pack('H*',$row['Token']).pack('n',strlen($payload)).$payload;
        //Send it to the server
        $PushResult = fwrite($fp, $msg, strlen($msg));
        if (!$PushResult) echo "Message not delivered! <br />";
        else echo "Message successfully delivered! <br />";
    };

    //Close connection to the server
    echo "Closing APNS connection...<br><br>";
    fclose($fp);
    mysqli_free_result($result);
}
mysqli_close($link);

我的iPhone脚本......

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.

//Register for push notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert)];
return YES;
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"registeredForPush"])
{
    //Remove spaces and brackets from deviceToken
    NSString* token  = [deviceToken description];
    token = [token stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];

    NSMutableString *params = [[NSMutableString alloc] initWithFormat:@"Token="];
    [params appendString:token];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.bluelineapps.net/****.php"] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:100.0];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if (connection)
    {
    //Show alert
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Thank you!" message:@"Thank you for registering for updates. Please rate this app in the AppStore after you've had some time to use it. Feedback is welcome and can be sent using the 'Feedback' tab below. Enjoy!" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
    [alert dismissWithClickedButtonIndex:0 animated:TRUE];
    [alert show];
    }
    else
    {
        //Show Error
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Registration error!" message:@"Failed to register for updates. Please try again later in your 'Settings' app. Sorry for the inconvenience." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alert dismissWithClickedButtonIndex:0 animated:TRUE];
        [alert show];
    }
    [[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"registeredForPush"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}
}

- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(@"Failed to get token, error: %@", error);
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Landing Zone Assistant" message:[userInfo valueForKeyPath:@"alert"] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
}

@end

更新

好的,所以删除所有移动配置配置文件,所有证书,所有.pem文件,所有内容,并重新生成开发和生产的所有证书,密钥,权限和配置文件后,我的问题仍然存在...... < / p>

使用沙盒网关发送消息到设备上的调试版本,成功。使用主Apple网关发送消息以在测试设备上的Ad Hoc版本上发布版本,不成功....

有什么想法吗?

我没有从APNS服务收到任何错误消息,一切都成功。没有构建错误。全新的最新证书......


更新

我在Apple技术支持here找到了这篇文章,并按照所有步骤检查了所有内容。据我所知,一切都检查出来。我的生产版本确实包含了生产的aps_environment。

我还发现this method用于生成.pem文件,这与我以前的尝试有点不同,所以我尝试了这个,但它仍然不起作用。我的代码仍然与上面相同,因为问题似乎在其他地方,但如果有人在通过PLEASE扫描时看到了什么让我知道。我只想让它发挥作用。

我很乐意在这个问题上给予赏金,但我没有足够的声誉,而且我一直试图通过帮助别人提出问题来获得一些。


更新

在搜索时,我发现Apple here的另一个文档中有一行说明“注意生产环境中的设备令牌和开发(沙箱)环境中的设备令牌不一样值。”所以我想另一个问题是。

对于开发和生产模式,deviceToken是否不同?


更新

我知道这已经很久了,但我试图说明我采取了哪些步骤来尝试自我解决这个问题。

我一直在文档中看到这个Entrust CA证书。我已经用它来验证与APNS网关的连接,但是在发送推送消息时我没有在我的连接中使用它,因为我看到的所有示例都没有显示使用它。这是否必要,如果是,那我该如何使用呢?


更新

我决定尝试使用PhoneGap重新开发我的应用并吸引更多受众群体,所以我现在暂时关闭它。谢谢大家的帮助。

1 个答案:

答案 0 :(得分:-1)

在查看代码之前,打开生产供应配置文件并仔细检查它是否有条目:

    <key>ProvisionsAllDevices</key><true/>

我猜这个设备是在开发配置文件中注册的,所以它在那里工作但不与prod一起工作的事实让我相信问题在于配置文件本身。您必须拥有Apple企业开发人员帐户才能创建可以配置任何设备的配置文件。