QT iOS谷歌云消息崩溃
我试图在Qt上编写的跨平台项目中实现远程推送通知 我发现谷歌为Android和iOS提供了谷歌云消息服务。() 我需要使用一些谷歌代码,并为每个平台编写一些本地代码(Android的Java和iOS的Objective C) 我阅读了Android部分并在我的项目中实现了它,它工作得很好 现在我尝试实现iOS部分() 有一些问题 首先,我不能在Qt项目中使用cocoapod,所以我必须手动链接必要的lib 这是我的Qt项目文件:QT iOS谷歌云消息崩溃,ios,objective-c,qt,google-cloud-messaging,apple-push-notifications,Ios,Objective C,Qt,Google Cloud Messaging,Apple Push Notifications,我试图在Qt上编写的跨平台项目中实现远程推送通知 我发现谷歌为Android和iOS提供了谷歌云消息服务。() 我需要使用一些谷歌代码,并为每个平台编写一些本地代码(Android的Java和iOS的Objective C) 我阅读了Android部分并在我的项目中实现了它,它工作得很好 现在我尝试实现iOS部分() 有一些问题 首先,我不能在Qt项目中使用cocoapod,所以我必须手动链接必要的lib 这是我的Qt项目文件: ios { ios_google_plist.files = $
ios {
ios_google_plist.files = $$PWD/ios/GoogleService-Info.plist
QMAKE_BUNDLE_DATA += ios_google_plist
QMAKE_INFO_PLIST = $$PWD/ios/Info.plist
LIBS += \
./ios/libs/libGGLInstanceIDLib.a \
./ios/libs/libGGLCloudMessaging.a \
./ios/libs/libGGLCore.a \
./ios/libs/libGcmLib.a \
./ios/libs/libProtocolBuffers.a \
./ios/libs/libGTMSessionFetcher_core.a \
./ios/libs/libGTMSessionFetcher_full.a \
./ios/libs/libGSDK_Overload.a \
./ios/libs/libGTM_AddressBook.a \
./ios/libs/libGTM_core.a \
./ios/libs/libGTM_DebugUtils.a \
./ios/libs/libGTM_GTMURLBuilder.a \
./ios/libs/libGTM_iPhone.a \
./ios/libs/libGTM_KVO.a \
./ios/libs/libGTM_NSDictionary+URLArguments.a \
./ios/libs/libGTM_NSScannerJSON.a \
./ios/libs/libGTM_NSStringHTML.a \
./ios/libs/libGTM_NSStringXML.a \
./ios/libs/libGTM_Regex.a \
./ios/libs/libGTM_RoundedRectPath.a \
./ios/libs/libGTM_StringEncoding.a \
./ios/libs/libGTM_SystemVersion.a \
./ios/libs/libGTM_UIFont+LineHeight.a \
./ios/libs/libGTMStackTrace.a
}
2015-08-21 16:59:50.735 MyCustomApp[475:96862] Attempted to configure [Identity, Analytics, AdMob, SignIn, AppInvite, CloudMessaging].
2015-08-21 16:59:50.735 MyCustomApp[475:96862] Successfully configured [].
2015-08-21 16:59:50.736 MyCustomApp[475:96862] Failed to configure [].
2015-08-21 16:59:50.736 MyCustomApp[475:96862] Subspecs not present, so not configured [Identity, Analytics, AdMob, SignIn, AppInvite, CloudMessaging].
2015-08-21 16:59:50.762 MyCustomApp[475:96862] didRegisterForRemoteNotificationsWithDeviceToken begin
2015-08-21 16:59:50.767 MyCustomApp[475:96862] didRegisterForRemoteNotificationsWithDeviceToken end
2015-08-21 16:59:50.787 MyCustomApp[475:96862] -[GGLInstanceIDTokenManager fetchTokenWithAuthorizedEntity:scope:keyPair:options:handler:]: unrecognized selector sent to instance 0x170623c20
2015-08-21 16:59:50.788 MyCustomApp[475:96862] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GGLInstanceIDTokenManager fetchTokenWithAuthorizedEntity:scope:keyPair:options:handler:]: unrecognized selector sent to instance 0x170623c20'
*** First throw call stack:
()
libc++abi.dylib: terminating with uncaught exception of type NSException
program received signal 6,thread:17a5e;qaddr:199071490;00:0000000000000000;01:0000000000000000;02:0000000000000000;03:37364e7001000000;04:fddd569401000000;05:60d2ca6f01000000;06:6e00000000000000;07:800f000000000000;08:0000000800000000;09:0000000400000000;0a:0002000000000000;0b:0000000000000000;0c:0000000000000000;0d:0000000000000000;0e:0200000000000000;0f:0000000000000000;10:4801000000000000;11:0000000000000000;12:0000000000000000;13:0600000000000000;14:1013079901000000;15:e89c059901000000;16:b0c7217001000000;17:a09ae60101000000;18:0000000000000000;19:7a54608901000000;1a:0000000000000000;1b:0000000000000000;1c:c0b7049901000000;1d:c0d1ca6f01000000;1e:28d2589501000000;1f:a0d1ca6f01000000;20:70f24e9501000000;21:00000000;metype:5;mecount:2;medata:10003;medata:6;
iOS应用程序构建成功,但在接收令牌时在某处崩溃
这是日志:
ios {
ios_google_plist.files = $$PWD/ios/GoogleService-Info.plist
QMAKE_BUNDLE_DATA += ios_google_plist
QMAKE_INFO_PLIST = $$PWD/ios/Info.plist
LIBS += \
./ios/libs/libGGLInstanceIDLib.a \
./ios/libs/libGGLCloudMessaging.a \
./ios/libs/libGGLCore.a \
./ios/libs/libGcmLib.a \
./ios/libs/libProtocolBuffers.a \
./ios/libs/libGTMSessionFetcher_core.a \
./ios/libs/libGTMSessionFetcher_full.a \
./ios/libs/libGSDK_Overload.a \
./ios/libs/libGTM_AddressBook.a \
./ios/libs/libGTM_core.a \
./ios/libs/libGTM_DebugUtils.a \
./ios/libs/libGTM_GTMURLBuilder.a \
./ios/libs/libGTM_iPhone.a \
./ios/libs/libGTM_KVO.a \
./ios/libs/libGTM_NSDictionary+URLArguments.a \
./ios/libs/libGTM_NSScannerJSON.a \
./ios/libs/libGTM_NSStringHTML.a \
./ios/libs/libGTM_NSStringXML.a \
./ios/libs/libGTM_Regex.a \
./ios/libs/libGTM_RoundedRectPath.a \
./ios/libs/libGTM_StringEncoding.a \
./ios/libs/libGTM_SystemVersion.a \
./ios/libs/libGTM_UIFont+LineHeight.a \
./ios/libs/libGTMStackTrace.a
}
2015-08-21 16:59:50.735 MyCustomApp[475:96862] Attempted to configure [Identity, Analytics, AdMob, SignIn, AppInvite, CloudMessaging].
2015-08-21 16:59:50.735 MyCustomApp[475:96862] Successfully configured [].
2015-08-21 16:59:50.736 MyCustomApp[475:96862] Failed to configure [].
2015-08-21 16:59:50.736 MyCustomApp[475:96862] Subspecs not present, so not configured [Identity, Analytics, AdMob, SignIn, AppInvite, CloudMessaging].
2015-08-21 16:59:50.762 MyCustomApp[475:96862] didRegisterForRemoteNotificationsWithDeviceToken begin
2015-08-21 16:59:50.767 MyCustomApp[475:96862] didRegisterForRemoteNotificationsWithDeviceToken end
2015-08-21 16:59:50.787 MyCustomApp[475:96862] -[GGLInstanceIDTokenManager fetchTokenWithAuthorizedEntity:scope:keyPair:options:handler:]: unrecognized selector sent to instance 0x170623c20
2015-08-21 16:59:50.788 MyCustomApp[475:96862] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GGLInstanceIDTokenManager fetchTokenWithAuthorizedEntity:scope:keyPair:options:handler:]: unrecognized selector sent to instance 0x170623c20'
*** First throw call stack:
()
libc++abi.dylib: terminating with uncaught exception of type NSException
program received signal 6,thread:17a5e;qaddr:199071490;00:0000000000000000;01:0000000000000000;02:0000000000000000;03:37364e7001000000;04:fddd569401000000;05:60d2ca6f01000000;06:6e00000000000000;07:800f000000000000;08:0000000800000000;09:0000000400000000;0a:0002000000000000;0b:0000000000000000;0c:0000000000000000;0d:0000000000000000;0e:0200000000000000;0f:0000000000000000;10:4801000000000000;11:0000000000000000;12:0000000000000000;13:0600000000000000;14:1013079901000000;15:e89c059901000000;16:b0c7217001000000;17:a09ae60101000000;18:0000000000000000;19:7a54608901000000;1a:0000000000000000;1b:0000000000000000;1c:c0b7049901000000;1d:c0d1ca6f01000000;1e:28d2589501000000;1f:a0d1ca6f01000000;20:70f24e9501000000;21:00000000;metype:5;mecount:2;medata:10003;medata:6;
如您所见,registrationHandler回调未被调用,而崩溃发生在google库的某个地方(在调用registrationHandler回调之前)
我使用google示例代码并做了一些更改,例如,我将AppDelegate接口重命名为QIOSApplicationDelegate(否则不调用Objective-C函数)
以下是Objective-C代码:
AppDelegateGoogle.h
#include <QtCore>
void registerDeviceForNotification_iOS_CPP(void);
#包括
无效登记设备通知(无效);
及
AppDelegateGoogle.mm
#import "Google/CloudMessaging.h"
#import <UIKit/UIKit.h>
#import "AppDelegateGoogle.h"
@interface QIOSApplicationDelegate : UIResponder <UIApplicationDelegate, GGLInstanceIDDelegate>
@property(nonatomic, strong) UIWindow *window;
@property(nonatomic, readonly, strong) NSString *registrationKey;
@property(nonatomic, readonly, strong) NSString *messageKey;
@property(nonatomic, readonly, strong) NSString *gcmSenderID;
@property(nonatomic, readonly, strong) NSDictionary *registrationOptions;
@property(nonatomic, strong) void (^registrationHandler)
(NSString *registrationToken, NSError *error);
@property(nonatomic, assign) BOOL connectedToGCM;
@property(nonatomic, strong) NSString* registrationToken;
@property(nonatomic, assign) BOOL subscribedToTopic;
@end
QIOSApplicationDelegate* pApp;
NSString *const SubscriptionTopic = @"/topics/global";
void registerDeviceForNotification_iOS_CPP(void)
{
[pApp registerDeviceForNotification_iOS];
}
@implementation QIOSApplicationDelegate
// [START register_for_remote_notifications]
- (void)registerDeviceForNotification_iOS {
// [START_EXCLUDE]
_registrationKey = @"onRegistrationCompleted";
_messageKey = @"onMessageReceived";
// Configure the Google context: parses the GoogleService-Info.plist, and initializes
// the services that have entries in the file
NSError* configureError;
[[GGLContext sharedInstance] configureWithError:&configureError];
if (configureError != nil) {
NSLog(@"Error configuring the Google context: %@", configureError);
}
_gcmSenderID = [[[GGLContext sharedInstance] configuration] gcmSenderID];
// [END_EXCLUDE]
// Register for remote notifications
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
// [END register_for_remote_notifications]
// [START start_gcm_service]
[[GCMService sharedInstance] startWithConfig:[GCMConfig defaultConfig]];
// [END start_gcm_service]
__weak QIOSApplicationDelegate* weakSelf = self;
// Handler for registration token request
_registrationHandler = ^(NSString *registrationToken, NSError *error){
NSLog(@"_registrationHandler called");
if (registrationToken != nil) {
NSLog(@"Registration Token: %@", registrationToken);
std::string strToken([registrationToken UTF8String]);
Device::sendRegistrationToServer(strToken);
} else {
NSLog(@"Registration to GCM failed with error: %@", error.localizedDescription);
}
};
}
// [START register_for_remote_notifications]
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
pApp = self;
return YES;
}
- (void)subscribeToTopic {
// If the app has a registration token and is connected to GCM, proceed to subscribe to the
// topic
if (_registrationToken && _connectedToGCM) {
[[GCMPubSub sharedInstance] subscribeWithToken:_registrationToken
topic:SubscriptionTopic
options:nil
handler:^(NSError *error) {
if (error) {
// Treat the "already subscribed" error more gently
if (error.code == 3001) {
NSLog(@"Already subscribed to %@",
SubscriptionTopic);
} else {
NSLog(@"Subscription failed: %@",
error.localizedDescription);
}
} else {
self.subscribedToTopic = true;
NSLog(@"Subscribed to %@", SubscriptionTopic);
}
}];
}
}
// [START connect_gcm_service]
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Connect to the GCM server to receive non-APNS notifications
[[GCMService sharedInstance] connectWithHandler:^(NSError *error) {
if (error) {
NSLog(@"Could not connect to GCM: %@", error.localizedDescription);
} else {
_connectedToGCM = true;
NSLog(@"Connected to GCM");
// [START_EXCLUDE]
[self subscribeToTopic];
// [END_EXCLUDE]
}
}];
}
// [END connect_gcm_service]
// [START disconnect_gcm_service]
- (void)applicationDidEnterBackground:(UIApplication *)application {
[[GCMService sharedInstance] disconnect];
// [START_EXCLUDE]
_connectedToGCM = NO;
// [END_EXCLUDE]
}
// [END disconnect_gcm_service]
// [START receive_apns_token]
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// [END receive_apns_token]
NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken begin");
// [START get_gcm_reg_token]
// Start the GGLInstanceID shared instance with the default config and request a registration
// token to enable reception of notifications
[[GGLInstanceID sharedInstance] startWithConfig:[GGLInstanceIDConfig defaultConfig]];
_registrationOptions = @{kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:@YES};
[[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:_gcmSenderID
scope:kGGLInstanceIDScopeGCM
options:_registrationOptions
handler:_registrationHandler];
// [END get_gcm_reg_token]
NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken end");
}
// [START receive_apns_token_error]
- (void)application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"Registration for remote notification failed with error: %@", error.localizedDescription);
// [END receive_apns_token_error]
NSDictionary *userInfo = @{@"error" :error.localizedDescription};
[[NSNotificationCenter defaultCenter] postNotificationName:_registrationKey
object:nil
userInfo:userInfo];
}
// [START ack_message_reception]
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"Notification received: %@", userInfo);
// This works only if the app started the GCM service
[[GCMService sharedInstance] appDidReceiveMessage:userInfo];
// Handle the received message
// [START_EXCLUDE]
[[NSNotificationCenter defaultCenter] postNotificationName:_messageKey
object:nil
userInfo:userInfo];
// [END_EXCLUDE]
}
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
NSLog(@"Notification received: %@", userInfo);
// This works only if the app started the GCM service
[[GCMService sharedInstance] appDidReceiveMessage:userInfo];
// Handle the received message
// Invoke the completion handler passing the appropriate UIBackgroundFetchResult value
// [START_EXCLUDE]
[[NSNotificationCenter defaultCenter] postNotificationName:_messageKey
object:nil
userInfo:userInfo];
handler(UIBackgroundFetchResultNoData);
// [END_EXCLUDE]
}
// [END ack_message_reception]
// [START on_token_refresh]
- (void)onTokenRefresh {
// A rotation of the registration tokens is happening, so the app needs to request a new token.
NSLog(@"The GCM registration token needs to be changed.");
[[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:_gcmSenderID
scope:kGGLInstanceIDScopeGCM
options:_registrationOptions
handler:_registrationHandler];
}
// [END on_token_refresh]
@end
#导入“Google/CloudMessaging.h”
#进口
#导入“AppDelegateGoogle.h”
@接口QIOSApplicationLegate:UIResponder
@属性(非原子,强)UIWindow*window;
@属性(非原子、只读、强)NSString*registrationKey;
@属性(非原子、只读、强)NSString*messageKey;
@属性(非原子、只读、强)NSString*gcmSenderID;
@属性(非原子、只读、强)NSDictionary*注册选项;
@属性(非原子,强)void(^registrationHandler)
(NSString*注册令牌,NSError*错误);
@属性(非原子,赋值)BOOL connectedToGCM;
@属性(非原子,强)NSString*registrationToken;
@属性(非原子,赋值)BOOL subscribedtototopic;
@结束
QIOSapplicationelegate*pApp;
NSString*const SubscriptionTopic=@“/主题/全局”;
无效注册设备通知(无效)
{
[pApp注册设备通知];
}
@实现QiosApplicationLegate
//[启动远程通知的注册\u]
-(无效)注册设备通知{
//[开始时不包括]
_registrationKey=@“onRegistrationCompleted”;
_messageKey=@“onMessageReceived”;
//配置Google上下文:解析GoogleService-Info.plist并初始化
//文件中包含条目的服务
n错误*配置错误;
[[GlgContext sharedInstance]配置错误:&configureError];
如果(配置错误!=nil){
NSLog(@“配置Google上下文时出错:%@”,配置错误);
}
_gcmSenderID=[[GGLContext sharedInstance]配置]gcmSenderID];
//[完]
//注册远程通知
UIUserNotificationType所有NotificationType=
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings*设置=
[UIUserNotificationSettings设置类型:allNotificationTypes类别:nil];
[[UIApplication sharedApplication]注册表通知设置:设置];
[[UIApplication sharedApplication]注册表项的删除];
//[用于远程通知的结束寄存器\u]
//[启动\u gcm\u服务]
[[GCMService sharedInstance]startWithConfig:[GCMConfig defaultConfig]];
//[结束-启动\u gcm\u服务]
__弱QIOSapplicationLegate*weakSelf=self;
//注册令牌请求的处理程序
_registrationHandler=^(NSString*registrationToken,NSError*error){
NSLog(@“_registrationhandlercalled”);
如果(注册令牌!=nil){
NSLog(@“注册令牌:%@”,注册令牌);
std::string strToken([registrationToken UTF8String]);
设备::sendRegistrationToServer(strToken);
}否则{
NSLog(@“注册到GCM失败,错误:%@”,错误。localizedDescription);
}
};
}
//[启动远程通知的注册\u]
-(BOOL)应用程序:(UIApplication*)应用程序
didFinishLaunchingWithOptions:(NSDictionary*)启动选项{
pApp=自我;
返回YES;
}
-(无效)下标{
//如果应用程序具有注册令牌并连接到GCM,则继续订阅
//话题
if(_registrationToken&&u connectedToGCM){
[[GCMPubSub sharedInstance]SubscribowithToken:\u registrationToken
主题:订阅主题
选项:无
处理程序:^(n错误*错误){
如果(错误){
//更温和地对待“已订阅”错误
如果(错误代码==3001){
NSLog(@“已订阅%@”,
下标图);
}否则{
NSLog(@“订阅失败:%@”,
错误。本地化描述);
}
}否则{
self.subscribedToTopic=true;
NSLog(@“订阅%@”,订阅主题);
}
}];
}
}
//[启动连接\u gcm\u服务]
-(无效)应用IDBECOMEACTIVE:(UIApplication*)应用{
//连接到GCM服务器以接收非APNS通知
[[GCMServi