IOS - qiosapplicationdelegate.h linking problem in QtCreator
-
QMAKE_LFLAGS += -lsqlite3
Uhuh :) it worked for _sqlite3 links, but there is still _OBJC_CLASS link.
QMAKE_LFLAGS += -lsqlite3 -ObjC
Then I tried with -ObjC. But I got an other error :
Undefined symbols for architecture arm64:
"_ABMultiValueReplaceLabelAtIndex", referenced from:
-[GSDK_GTMABMutableMultiValue replaceLabelAtIndex:withLabel:] in libGTM_AddressBook.a(GTMABAddressBook.o)
"_ABMultiValueGetPropertyType", referenced from:
-[GSDK_GTMABMultiValue propertyType] in libGTM_AddressBook.a(GTMABAddressBook.o)
...QMAKE_LFLAGS += -lsqlite3 -ObjC -framework
I added -framework. An other error :
ld: framework not found -stdlib=libc++QMAKE_LFLAGS += -lsqlite3 -ObjC -framework -stdlib=libstdc++
With -stdlib=libstdc++, the error is :
ld: framework not found -stdlib=libstdc++ -
It's woking with those linker options :
QMAKE_LFLAGS += -ObjC -lsqlite3 -lz -framework "AddressBook" -framework "AssetsLibrary" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreMotion" -framework "MessageUI" -framework "SystemConfiguration"
Thx again, Leonardo. I'm nearer from the Notification Push system.
-
Do you mean I don't need all of those libraries :
ios/Pods/GGLInstanceID/Libraries/libGGLInstanceIDLib.a \ ios/Pods/Google/Libraries/libGGLCloudMessaging.a \ ios/Pods/Google/Libraries/libGGLCore.a \ ios/Pods/GoogleCloudMessaging/Libraries/libGcmLib.a \ ios/Pods/GoogleInterchangeUtilities/Libraries/libProtocolBuffers.a \ ios/Pods/GoogleIPhoneUtilities/Libraries/libGIP_Reachability.a \ ios/Pods/GoogleNetworkingUtilities/Libraries/libGTMSessionFetcher_core.a \ ios/Pods/GoogleNetworkingUtilities/Libraries/libGTMSessionFetcher_full.a \ ios/Pods/GoogleSymbolUtilities/Libraries/libGSDK_Overload.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_AddressBook.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_core.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_DebugUtils.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_GTMURLBuilder.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_iPhone.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_KVO.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_NSData+zlib.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_NSDictionary+URLArguments.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_NSScannerJSON.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_NSStringHTML.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_NSStringXML.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_Regex.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_RoundedRectPath.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_StringEncoding.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_SystemVersion.a \ ios/Pods/GoogleUtilities/Libraries/libGTM_UIFont+LineHeight.a \ ios/Pods/GoogleUtilities/Libraries/libGTMStackTrace.a
I have a bug about including GoogleService-Info.plist, I'm not sure about the right way to do.
In the .pro file, I have this :QMAKE_BUNDLE_DATA += ios/GoogleService-Info.plist QMAKE_INFO_PLIST = ios/Info.plist
The GoogleService-Info.plist should be ok, I already tested it in the example project of Google.
There is this error during execution :Clearing previous value from *error Could not locate configuration file: 'GoogleService-Info.plist'. Shared configuration dictionary was nil Could not locate configuration file: 'GoogleService-Info.plist'. *** Assertion failure in -[QIOSApplicationDelegate application:didFinishLaunchingWithOptions:], /Users/vi/myproject/ios/src/MyAppDelegate.m:74 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error configuring Google services: Error Domain=com.google.greenhouse Code=-100 "Unable to configure GGL." UserInfo={NSLocalizedRecoverySuggestion=Check formatting and location of GoogleService-Info.plist., NSLocalizedDescription=Unable to configure GGL., NSLocalizedFailureReason=Unable to parse supplied GoogleService-Info.plist. See log for details.}' *** First throw call stack: (0x18537cf48 0x199f2ff80 0x18537ce18 0x186270a1c 0x1000ccea8 0x18a985324 0x18abb3acc 0x18abb7e0c 0x18abb4f50 0x18f19b7c4 0x18f19bb44 0x185334544 0x185333fd8 0x185331cd8 0x185260ca0 0x18a97e1c8 0x18a978ffc 0x10016f794 0x19a77e8b8) libc++abi.dylib: terminating with uncaught exception of type NSException
-
I mean you don't need to have the GCM service and library. I couldn't test it yet, but I have a similar app, and their guide for iOS suggests that once you have a registration token, you're ready to receive push notifications.
Maybe you should give it a try and test it for us. I think that the GCM library is useful for sending and receiving real time messages, like in messaging apps. But other than that, if your application is not in foreground, Google is forced to use the same push delivery system any of us would have to use. And for that the token is enough. No need for a GCM service or GoogleService-Info.plist. Here are the flags I'm using:
-ObjC -framework AddressBook -lGGLInstanceIDLib -lGTM_iPhone -lGTM_core -lGTM_UIFont+LineHeight -lGTM_SystemVersion -lGTM_StringEncoding -lGTM_RoundedRectPath -lGTM_Regex -lGTM_NSStringXML -lGTM_NSStringHTML -lGTM_NSScannerJSON -lGTM_NSDictionary+URLArguments -lGTM_NSData+zlib -lGTM_KVO -lGTM_GTMURLBuilder -lGTM_DebugUtils -lGTM_AddressBook -lGTMStackTrace -lGTMSessionFetcher_full -lGTMSessionFetcher_core -lGSDK_Overload
Using these libraries:
GGLInstanceID, GoogleNetworkingUtilities, GoogleUtilities, GoogleSymbolUtilities
-
I've tried something, but I have a bug during the execution of didRegisterForRemoteNotificationsWithDeviceToken function :
-[QIOSApplicationDelegate gcmSenderID]: unrecognized selector sent to instance 0x13e524860 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[QIOSApplicationDelegate gcmSenderID]: unrecognized selector sent to instance 0x13e524860'
There is the function :
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { GGLInstanceIDConfig *instanceIDConfig = [GGLInstanceIDConfig defaultConfig]; instanceIDConfig.delegate = self; [[GGLInstanceID sharedInstance] startWithConfig:instanceIDConfig]; self.registrationOptions = @{kGGLInstanceIDRegisterAPNSOption:deviceToken, kGGLInstanceIDAPNSServerTypeSandboxOption:@YES}; self.gcmSenderID = @"MYSENDERID"; [[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:self.gcmSenderID scope:kGGLInstanceIDScopeGCM options:self.registrationOptions handler:self.registrationHandler]; }
There is the didFinishLaunchingWithOptions function :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.registrationKey = @"onRegistrationCompleted"; self.gcmSenderID = @"MYSENDERID"; // Register for remote notifications if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { // iOS 7.1 or earlier UIRemoteNotificationType allNotificationTypes = (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge); [application registerForRemoteNotificationTypes:allNotificationTypes]; } else { // iOS 8 or later UIUserNotificationType allNotificationTypes = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge); UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; [[UIApplication sharedApplication] registerForRemoteNotifications]; } __weak typeof(self) weakSelf = self; // Handler for registration token request self.registrationHandler = ^(NSString *registrationToken, NSError *error) { if (registrationToken != nil) { weakSelf.registrationToken = registrationToken; NSLog(@"Registration Token: %@", registrationToken); //[weakSelf subscribeToTopic]; NSDictionary *userInfo = @{@"registrationToken":registrationToken}; [[NSNotificationCenter defaultCenter] postNotificationName:weakSelf.registrationKey object:nil userInfo:userInfo]; } else { NSLog(@"Registration to GCM failed with error: %@", error.localizedDescription); NSDictionary *userInfo = @{@"error":error.localizedDescription}; [[NSNotificationCenter defaultCenter] postNotificationName:weakSelf.registrationKey object:nil userInfo:userInfo]; } }; return YES; }
-
According to this stackoverflow post, I should use the gstatic version of GCM.
I don't have an iphone for testing now, I'll test tonight. -
I tried without GCM service or GoogleService-Info.plist, but i haven't good results.
Then I came back to GoogleService-Info.plist loading problem.
Before I got this error :
Could not locate configuration file: 'GoogleService-Info.plist'.
But now, I have a better error :
The configuration file is not a dictionary: 'GoogleService-Info.plist'.
It looks better, isn't it ? :D .. but it still doesn't workThere is the fix in .pro file :
GInfo.files = ios/GoogleService-Info.plist GInfo.path = GoogleService-Info.plist QMAKE_BUNDLE_DATA += GInfo
-
I don't get your code. I can compile successfully without GCM service. Here's a simplified version of my code:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { GGLInstanceIDConfig* idConfig = [GGLInstanceIDConfig defaultConfig]; idConfig.delegate = self; [[GGLInstanceID sharedInstance] startWithConfig:idConfig]; //==================================== if([application respondsToSelector:@selector(registerForRemoteNotifications)]){ [application registerForRemoteNotifications]; }else{ [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert]; } return YES; } -(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { GGLInstanceID* idInstance = [GGLInstanceID sharedInstance]; [idInstance tokenWithAuthorizedEntity:@"123456789" scope:kGGLInstanceIDScopeGCM options:@{kGGLInstanceIDRegisterAPNSOption : deviceToken, kGGLInstanceIDAPNSServerTypeSandboxOption : @0} handler:^(NSString *token, NSError *error) { if(token != nil){ // } }]; }
-
Thx to share your code.
It's simpler than the Google sample.I'm just wondering what is the difference between putting startWithConfig in didFinishLaunchingWithOptions as you did, or put it in didRegisterForRemoteNotificationsWithDeviceToken as it's done in Google sample ?
I guess it's working, I just have this error, because I'm working on simulator :
Registration for remote notification failed with error: REMOTE_NOTIFICATION_SIMULATOR_NOT_SUPPORTED_NSERROR_DESCRIPTIONI wait the device to make the final test.
-
Hello Leonardo,
Now GCM service is working fine for 2 ouf of 3 cases :
-
When the app is active -> OK
-
When the app is in background, then I click on the notif popup (in IOS UI), then the app comes back -> OK
-
But for the last case, there is a bug :
The app is closed. Then a notif popup is comming (in IOS UI), but when I click on it -> The app isn't shown back. The phone is almost blocked. It looks like the app is running in background but with a blackscreen. I don't even know how to have a log trace, because the app was previously closed manually.
I hope you can help me again. Any way, I'm reaching the end through your help.
-
-
Hi. It worked in all three cases for me. The only time I could reproduce the issue you mentioned was when I launched the app from XCode and then closed it manually on the device. An error was thrown on XCode and the app was like suspended. In that case indeed it felt like the device was frozen, but it was so just because XCode was holding the app.
-
Thanks for your test.
You are right, I closed manually the app. I didn't know that xcode or qt holds the app.
Now everything looks great. I just need to check if the third case code is working, I have something like that :- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { if (launchOptions != nil) { NSDictionary* notif = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; if (notif) { NSString* type_n = [notif valueForKey:@"gcm.notification.type"]; if (type_n) { std::string* type = new std::string([type_n UTF8String]); MyNotif::setExtraType(type); } } } ... }
-
Hi. I don't think you need to check for the notification type, because there will be no other one. Anyway, be careful, because didFinishLaunchingWithOptions will run before your main() from Qt. It means that even QApplication won't be available by then.