类似的问题在这里:jQueryMobile,Phonegap和设备令牌-iOS
场景是,我有这个基于PhoneGap网络的应用程序,本地iOS帮助我在APN上注册设备,我在服务器数据库中收到了设备令牌。
问题1:如何使用PhoneGap将注册用户(通过UIWebView)与此设备令牌关联?
- 我现在想的是编写一个自定义插件,并在用户注册期间传递设备令牌。还有更好的选择吗
问题2:由于device_token可以随时更改,我应该如何将此用户重新链接到此device_toke?
- 也许每当用户登录时,我都会做一个window.plugins.PluginName.getDeviceToken并同步它
{user_id:123, old_device_token: 'xxxx..', new_device_token: 'xxx...'}
Fyi,这个应用程序是为一个事件而构建的,客户端已经在这个移动应用程序上请求了人与人之间的消息。当"John Doe"收到朋友的消息时,你如何向他推送新消息通知?-问题是如何将"John Doe"链接到特定的设备_token?
这不能太特定于iOS,因为该应用程序也必须部署在Android上(C2DM)。
欢迎任何帮助!
编辑:可能的解决方案
不安的研究出现了这个可能的解决方案:
- [本机]应用程序已启动-APN注册已启动,收到device_token
- [本机]将此device_token存储到本地存储(CoreData/SqlLite或Property Lists?)中,并将其发送到服务器以进行device_toke注册
- [WebView]每当用户登录或注册时,都会通过PhoneGap查询此设备_token,对其进行哈希处理并发送到服务器以进行登录、比较和链接
任何不可预见的情况都有问题吗?
编辑:回答
我的完整工作解决方案张贴在答复中。点击此处查看:https://stackoverflow.com/a/9628592/534862
为了完整起见,这是我使用@TDeBailleul解决方案后的解决方案。转到科尔多瓦。(仅在iOS上测试。在我完成Android版本后,我将发布一个插件:
环境
- Cordova 1.5.0(以前的PhoneGap)
- Xcode 4.3.1
- iOS 5.1
- Mac OS X 10.7.3
- 不要使用自动参考计数(ARC)以避免编译错误
- 通过这个超长的教程,准备好你的推送通知证书
工作流程
- [本机]应用程序已启动-APN注册已启动,并且在服务器端接收到device_token
- [本机]应用程序将令牌存储在
AppDelegate
中,要获取令牌,请使用以下代码中的PushToken
- [WebView]每当用户登录或注册时,令牌都会通过Cordova(前身为PhoneGap)插件调用,进行哈希处理,然后发送到服务器进行登录、匹配并将用户链接到特定设备
下面是我的完整工作代码,用于进行令牌的本地提取。服务器部分只是将帐户链接到设备。你应该知道如何通过你最喜欢的服务器端应用程序来实现它。
AppDelegate.h
@interface AppDelegate : NSObject < UIApplicationDelegate, UIWebViewDelegate, CDVCommandDelegate > {
...
NSString* token;
...
}
...
...
...
@property (retain, nonatomic) NSString* token;
AppDelegate.m
注意:我是一个Obj-C新手,我也尝试将令牌发布到我的服务器。如果您不需要过帐机制,请在didRegisterForRemoteNotificationsWithDeviceToken
中保留前5行(直到'self.token = dt
...
@synthesize token;
...
- (BOOL) application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
...
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(@"Did finish launching with device token %@", deviceToken);
NSString *dt = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
dt = [dt stringByReplacingOccurrencesOfString:@" " withString:@""];
self.token = dt;
NSString *dv = [[UIDevice currentDevice] systemVersion];
NSString *dn = [[UIDevice currentDevice] systemName];
NSString *nick = [[UIDevice currentDevice] name];
NSString *model = [[UIDevice currentDevice] model];
NSString *uniqueIdentifier = [[UIDevice currentDevice] uniqueIdentifier];
NSMutableString *postData = [NSMutableString stringWithString: @"&deviceToken="];
[postData appendString:dt];
[postData appendFormat:@"&uniqueIdentifier=%@&application_uuid=5ade8400-e29c-41d4-a716-3641972a2ec6", uniqueIdentifier];
[postData appendFormat:@"&source=ios&name=%@&model=%@&systemName=%@&systemVersion=%@", nick, model, dn, dv];
NSString* escapedURLString = [postData stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
@try {
NSData *postData = [escapedURLString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL: [NSURL URLWithString:@"{YOUR URL TO POST TOKEN TO SERVER}"]
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval: 180];
NSString *postLength = [[NSString alloc] initWithFormat: @"%d", [postData length]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (conn) {
//??
}else{
//??
}
}
@catch (NSException *exception) {
NSLog(@"Exception %@", exception);
}
}
...
PushToken.h
#import <Foundation/Foundation.h>
#import <CORDOVA/CDVPlugin.h>
@interface PushToken : CDVPlugin {
NSString* callbackID;
}
@property (nonatomic, copy) NSString* callbackID;
- (void) getToken:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
@end
PushToken.m
#import "PushToken.h"
#import "AppDelegate.h"
@implementation PushToken
@synthesize callbackID;
- (void)getToken:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options {
NSLog(@"Did called getToken");
self.callbackID = [arguments pop];
NSString *token = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).token;
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:[token stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
if (token.length != 0) {
[self writeJavascript: [pluginResult toSuccessCallbackString:self.callbackID]];
}else{
[self writeJavascript: [pluginResult toErrorCallbackString:self.callbackID]];
}
}
@end
PushToken.js
var PushToken = {
/**
* Get token from the device
* @param {array} types - By default is ['getToken']
* @param {function} success Success callback, with token
* @param {function} fail Failure callback, with null
*/
getToken: function(types, success, fail) {
return Cordova.exec(success, fail, "PushToken", "getToken", types);
},
/**
* For the sake of iOS, we need an install function
*/
install: function() {
window.plugins = window.plugins || {};
window.plugins.PushToken = PushToken;
}
};
/**
* For the rest of the devices
*/
window.plugins = window.plugins || {};
window.plugins.PushToken = PushToken;
用法
document.addEventListener('deviceready', function() {
if (typeof PushToken == 'object') {
PushToken.install();
}
PushToken.getToken(['getToken'], function(token) {
callback(token);
}, function() {
callback(null);
});
});
您应该能够从Javascript端获取令牌;)
玩得开心!
干杯
前面的答案确实是解决这个问题的好方法,而且他们以非常正式的方式来解决这个问题。然而,如果你想要一种快速而肮脏的方法来解决问题,你可以简单地这样做:
在didRegisterForRemoteNotificationsWithDeviceToken底部添加
NSString* jsString = [NSString stringWithFormat:@"var deviceToken = "%@";", deviceToken];
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsString];
在您的javascript中
deviceId = (typeof deviceToken !== "undefined") ? deviceToken : null;
好吧,我终于制作了一个插件,它似乎可以工作
1-确保您的PhoneGap Xcode项目已针对iOS 4 SDK进行了更新。
2-在插件文件夹中创建一个PushToken文件夹,添加以下PushToken.m和PushTokon.h文件,然后使用"为任何添加的文件夹创建组"将文件夹拖动到XCode中的插件文件夹
3-将PushToken.js文件添加到磁盘上的www文件夹中,并在html文件中添加对.js文件的引用作为标记
4-在PhoneGap.plist 的插件中添加带有密钥PushToken和字符串值PushToken的新条目
PushToken.h
#import <Foundation/Foundation.h>
#import <PhoneGap/PGPlugin.h>
@interface PushToken : PGPlugin{
NSString* callbackID;
}
@property (nonatomic, copy) NSString* callbackID;
- (void) getToken:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
@end
PushToken.m
#import "PushToken.h"
#import "AppDelegate.h"
@implementation PushToken
@synthesize callbackID;
-(void)getToken:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options {
self.callbackID = [arguments pop];
NSString *token = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).token;
PluginResult* pluginResult = [PluginResult resultWithStatus:PGCommandStatus_OK messageAsString:[token stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
if(token.length != 0)
{
[self writeJavascript: [pluginResult toSuccessCallbackString:self.callbackID]];
}else {
[self writeJavascript: [pluginResult toErrorCallbackString:self.callbackID]];
}
}
@end
PushToken.js
var PushToken = {
getToken: function(types, success, fail) {
return PhoneGap.exec(success, fail, "PushToken", "getToken", types);
}
};
如何使用
PushToken.getToken(
["getToken"] ,
function(token) {
console.log("Token : "+token);
},
function(error) {
console.log("Error : rn"+error);
}
);
AppDelegate.h
@interface AppDelegate : PhoneGapDelegate {
NSString* invokeString;
NSString* token;
}
@property (copy) NSString* invokeString;
@property (retain, nonatomic) NSString* token;
AppDelegate.m
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
self.token = [[[[deviceToken description]
stringByReplacingOccurrencesOfString: @"<" withString: @""]
stringByReplacingOccurrencesOfString: @">" withString: @""]
stringByReplacingOccurrencesOfString: @" " withString: @""];
NSLog(@"My token is: %@", self.token);
}
我在PhoneGap 1.1 上成功了
希望这能帮助