Integrating google analytics into iOS app - ios

I'm following the instructions on here to integrate google analytics into my app: https://developers.google.com/analytics/devguides/collection/ios/v3/?ver=swift#get-config
I'm at the point where I need to initialize analytics for my app. I've added this code in my AppDelegate.swift file:
import UIKit
import <Google/Analytics.h>
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions:[NSObject: AnyObject]?) -> Bool {
**// Configure tracker from GoogleService-Info.plist.
NSError *configureError;
[[GGLContext sharedInstance] configureWithError:&configureError];
NSAssert(!configureError, #"Error configuring Google services: %#", configureError);
// Optional: configure GAI options.
GAI *gai = [GAI sharedInstance];
gai.trackUncaughtExceptions = YES; // report uncaught exceptions
gai.logger.logLevel = kGAILogLevelVerbose; // remove before app release**
}
I'm getting the following error messages.
For my import <Google/Analytics.h> line, I'm getting this message:'Consecutive statements on a line must be separated by ';'.
For the rest of the code I'm getting several errors, although I simply copied the code in the tutorial into my file. See my screenshot.
enter image description here

You're getting this issue since you're in a Swift project. You'll need to create an Objective-C bridging header, and add the import statement there. Afterwards, everything should work properly. Check out this SO answer for more details:
https://stackoverflow.com/a/24005242/1784384

Related

pod 'GoogleAnalytics' in swift 4 won't run

I read this instructions to use google analytics in my app
https://developers.google.com/analytics/devguides/collection/ios/v3/?ver=swift
so I installed pod 'GoogleAnalytics' into my app and created a .h file in my swift application
so here is my h file codes in my app
#ifndef analytic_h
#define analytic_h
#import <Google/Analytics.h>
#endif /* analytic_h */
and here is my app Delegate codes But this code does not recognize GAI
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
guard let gai = GAI.sharedInstance() else {
assert(false, "Google Analytics not configured correctly")
}
gai.tracker(withTrackingId: "UA-xxxxxxxxx-x")
// Optional: automatically report uncaught exceptions.
gai.trackUncaughtExceptions = true
// Optional: set Logger to VERBOSE for debug information.
// Remove before app release.
gai.logger.logLevel = .verbose;
return true
}
I received this error for GAI
Use of unresolved identifier 'GAI'
My research on this-
Case 1- Adding Bridging header manually
I added .h file with name "MyProject-Bridging-Header.h" in the project.
And I received a file having content-
#ifndef MyProject-Bridging-Header_h
#define MyProject-Bridging-Header_h
#endif /* MyProject-Bridging-Header_h */
And then I tried adding one of the followings-
#import <GAI.h>
#import <Google/Analytics.h>
But none of them were working.
Case 2 - Adding bridging header automatically
For this, I added "Objective-C File" and it gave a prompt to add bridging header automatically and I accepted. In that bridging header file, I added
#import <GAI.h>
then it built like a charm and after that, I removed the line above and added -
#import <Google/Analytics.h>
It failed saying Google/Analytics.h not found.

Why IOS app is crashing while using Google Places API?

According to Google Doc here I tried whatever they said to do but all my efforts are in vain due to this error. But I didn't any change in info.plist.
2016-10-08 16:55:36.045 ContactApp[2674:83727] *** Terminating app due to uncaught exception 'GMSPlacesException', reason: 'Google Places API for iOS must be initialized via [GMSPlacesClient provideAPIKey:...] prior to use'
In my AppDelegate.swift I did look like below
import UIKit
import GoogleMaps
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
GMSServices.provideAPIKey("**********************")
return true
}
}
and I simply copied code and pasted to my controller. Here is also a link of my controller here
what can I do? Please provide any suggestion.
Use
GMSPlacesClient.provideAPIKey("YOUR_API_KEY")
instead of
GMSServices.provideAPIKey("**********************")

iOS swift You must specify clientID Exception in google integration

Code:
let signIn = GPPSignIn.sharedInstance()
signIn.shouldFetchGooglePlusUser = true
signIn.clientID = "912597493260-qg351fl8olmnmjl8qobos8n6u909jp0o.apps.googleusercontent.com"
signIn.scopes = [kGTLAuthScopePlusLogin];
signIn.trySilentAuthentication();
GIDSignIn.sharedInstance().signInSilently()
signIn.delegate = self
due to uncaught exception 'NSInvalidArgumentException', reason: 'You must specify |clientID| for |GIDSignIn|
I double checked my code.Even i set client-id getting this exception.Where i went wrong?any help will be appreciated.thanks in advance
I was following Google's own guide for adding Sign-In here. I followed it step by step - integrated the google configuration file too. As per the guide, if the configuration file was included, setting the client id manually was not required. Unfortunately, I encountered exactly the same error when I run the app and hit the Sign-In button:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'You must specify |clientID| for |GIDSignIn|'
Solution:
For some reason, clientID was not automatically picked from the configuration file. We should instead configure the GIDSignIn object directly, (using the client ID found in the GoogleService-Info.plist file) in the app delegate's application:didFinishLaunchingWithOptions: method:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Initialize sign-in
var configureError: NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
GIDSignIn.sharedInstance().clientID = "Cliend id From GoogleService-Info.plist file"
GIDSignIn.sharedInstance().delegate = self
return true
}
Also, if you are using Firebase, you can do it this way too:
GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
It looks like the auto-generated config file, GoogleService-Info.plist, will include the wrong credentials by default; it includes the Web Client credentials instead of the iOS app credentials.
You need to correct the Client ID and the Reverse Client ID in the GoogleService-Info.plist.
Since these credentials are also used in your app's URLSchemes, you need to correct this there too.
I was also facing the same issue. I followed every step as per the documentation by https://firebase.google.com/docs/auth/ios/google-signin#swift_9 .
At last, I tried adding Client ID manually on my Controller's viewDidLoad and it worked after a long struggle.
Refer the code below. Replace your project specific Client-ID from GoogleService-info.plist in place of ClientID :
class IntroController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
GIDSignIn.sharedInstance().clientID = "*ClientID*"
GIDSignIn.sharedInstance()?.presentingViewController = self
GIDSignIn.sharedInstance().signIn()
}
}
The clientId definitely does get picked up from the .plist file. If it appears not to be, it is likely that your code is attempting to use the sign-in object before it has been properly configured. Set a breakpoint on your configureWithError line, and make sure that it gets hit before any attempt to set a delegate, perform silent sign-in, etc.
Looks like the sign in method has now been updated by google, I was implementing the Google Calendar for iOS app and I found the following code for Sign In:
func applicationDidFinishLaunching(_ application: UIApplication) {
// Initialize sign-in
var configureError: NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError!)")
}
in their document which gave the same error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'You must specify |clientID| for |GIDSignIn|'
I took the lines which were inside:
func applicationDidFinishLaunching(_ application: UIApplication)
and put them in this method and sign in worked:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
Code for refernce:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// Initialize sign-in
var configureError: NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError!)")
return true
}
You may need to obtain GoogleService-Info.plist from https://console.firebase.google.com rather than https://console.developers.google.com/.
Using Firebase remember also that you have to call Firebase.configure() function before you set the clientId. Otherwise, it won't work.

AppConnect:Error : AppConnect is unable to start because [UIApplication sharedApplication] is not an instance of AppConnectUIApplication

I am getting an error, While accessing MDM using AppConnect SDK in swift 1.2.
Error :
[AppConnect:Error] AppConnect is unable to start because
[UIApplication sharedApplication] is not an instance of
AppConnectUIApplication.
Code Snippet :
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, AppConnectDelegate {
var window: UIWindow?
var appct : AppConnect!;
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
// Initialize the AppConnect library
AppConnect.initWithDelegate(self)
self.appct = AppConnect.sharedInstance()
self.appct.startWithLaunchOptions(launchOptions)
return true
}
}
Application is crashing at self.appct = AppConnect.sharedInstance()
Comment out #UIApplicationMain and change your main.swift file to the following:
import Foundation
UIApplicationMain(Process.argc, Process.unsafeArgv, "AppConnectUIApplication", NSStringFromClass(AppDelegate))
For more information, follow the setup instructions in the Documentation folder of the SDK source. (You have to make sure you follow the instructions of the document that matches the SDK that you are using since MI changes things frequently.)
My solution was to set a new key/value in the plist:
Principal class AppConnectUIApplication
or in source mode:
<key>NSPrincipalClass</key>
<string>AppConnectUIApplication</string>
Hope it help you

Exception:Google Maps SDK for iOS must be initialized via [GMSServices provideAPIKey:...] prior to use

I am trying to implement Google Maps SDK into my project using Swift 2.0. I follow this but when running this, my app is getting the following error:
2015-08-25 19:05:17.337 googleMap[1919:54102] *** Terminating app due to uncaught exception 'GMSServicesException', reason: 'Google Maps SDK for iOS must be initialized via [GMSServices provideAPIKey:...] prior to use
*** First throw call stack:
(
0 CoreFoundation 0x00000001058499b5 __exceptionPreprocess + 165
...
...
...
31 UIKit 0x000000010606699e UIApplicationMain + 171
32 googleMap 0x00000001034b720d main + 109
33 libdyld.dylib 0x0000000107fba92d start + 1
34 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I have tried all possible solutions from StackOverflow.
You need to set this both in didFinishLaunchingWithOptions
GMSPlacesClient.provideAPIKey("Your key")
GMSServices.provideAPIKey("Your key")
Just adding to Rajasekaran Gopal
Remember to add
import GoogleMaps
import GooglePlaces
then
GMSPlacesClient.provideAPIKey("Your key")
GMSServices.provideAPIKey("Your key")
in didFinishLaunchingWithOptions
I just had the same problem. I created a GMSMapView object and it was initialized before maybe the api key could be read. So I moved it inside the viewDidLoad method and problem solved.
Before :
class ViewController: ..... {
let mapView = GMSMapView()
After :
class ViewController: ..... {
var mapView : GMSMapView?
override viewDidLoad(){
mapView = GMSMapView()
Here is a Google Maps tutorial for Swift:
http://www.appcoda.com/google-maps-api-tutorial/
Below is quoted from Google Maps Documentation:
Step 5: Get an iOS API key
Using an API key enables you to monitor your application's API usage,
and ensures that Google can contact you about your application if
necessary. The key is free, you can use it with any of your
applications that call the Google Maps SDK for iOS, and it supports an
unlimited number of users. You obtain an API key from the Google
Developers Console by providing your application's bundle identifier.
If your project doesn't already have a key for iOS applications,
follow these steps to create an API key from the Google Developers
Console:
In the sidebar on the left, select Credentials.
If your project doesn't already have an iOS API key, create one now by selecting Add credentials > API key > iOS key.
In the resulting dialog, enter your app's bundle identifier. For example: com.example.hellomap.
Click Create.
Your new iOS API key appears in the list of API keys for your
project. An API key is a string of characters, something like this:
AIzaSyBdVl-cTICSwYKrZ95SuvNw7dbMuDt1KG0
Add your API key to your AppDelegate.m as follows:
Add the following import statement:
#import GoogleMaps;
Add the following to your application:didFinishLaunchingWithOptions: method, replacing API_KEY with your API key:
[GMSServices provideAPIKey:#"API_KEY"];
Source
If you already set GMSMapView class to your view in interface builder, make GMSServices.provideAPIKey("API key") in initialization methods of viewController which contains GMSMapView.
You should set up API keys before you set up the UIWindow in AppDelgate, if your initial View Controller uses GoogleMaps.
For example:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//MARK: Google Maps setup
GMSServices.provideAPIKey("YOUR API KEY")
GMSPlacesClient.provideAPIKey("YOUR API KEY")
let window = UIWindow(frame: UIScreen.main.bounds)
window.backgroundColor = UIColor.white
window.makeKeyAndVisible()
window.rootViewController = ViewController()
self.window = window
return true
}
In my app i provided key to GMSPlacesClient in AppDelegate -didFinishLaunchingWithOptions
Ex:
#import GooglePlaces;
#import GoogleMaps;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GMSServices provideAPIKey:#"You key"];
[GMSPlacesClient provideAPIKey:#"Your key"];
}
For Swift:
import GoogleMaps
import GooglePlaces
//in application(_:didFinishLaunchingWithOptions:)
GMSServices.provideAPIKey("YOUR_API_KEY")
GMSPlacesClient.provideAPIKey("YOUR_API_KEY")
in my case --didFinishLaunchingWithOptions-- method didn't call because i updated swift version. first make sure this method called normally. and in my case i didn't need to GMSPlacesClient.provideAPIKey("Your key"). however you can initial GMSServices in your initial viewcontroller (if its not contain map or related objet to it)
You are skipping provideAPIKey in your AppDelegate check project
Your_PROJECT -> ios -> Runner -> AppDelegate.m
Replace your file code with below snippet add your APIKEY
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#import "GoogleMaps/GoogleMaps.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GMSServices provideAPIKey:#"GOOGLE_API_KEY"];
[GeneratedPluginRegistrant registerWithRegistry:self];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
#end
Google Maps SDK for iOS must be initialized via [GMSServices provideAPIKey:...]
XCODE 12.0.1, Swift 5
I was applying constraints to Google Map View by initialising GMSMapView like this:-
private var googleMapsView : GMSMapView = {
let mainView = GMSMapView()
mainView.translatesAutoresizingMaskIntoConstraints = false
mainView.isMyLocationEnabled = true
return mainView
}()
& I was getting this same error, so I tried this making it a lazy property:-
lazy private var googleMapsView : GMSMapView = {
let mainView = GMSMapView()
mainView.translatesAutoresizingMaskIntoConstraints = false
mainView.isMyLocationEnabled = true
return mainView
}()
& voila! It worked like a charm.
Ensure that the lines you added to AppDelegate.m are actually being executed.
Since the integration with Flipper around react-native v0.62, a portion of the AppDelegate.m file is guarded by an ifdef FB_SONARKIT_ENABLED. If Flipper isn't enabled for whatever reason, any code inbetween the ifdef and the closing endif lines will not be executed. Make sure you paste the #import above the ifdef, and the [GMSServices] line in the didFinishLaunchingWithOptions method, immediately after the opening curly brace ({).
More info on Flipper in React Native: https://fbflipper.com/docs/features/react-native/
Added in the necessery functions providing the API Key in your AppDelegate and still getting this issue? Don't forget to ENABLE the specific API you need (i.e. Maps SDK for iOS/Android) in the Google Cloud Console as well:
https://console.cloud.google.com/apis/library
It may take a few minutes for the API to enable/propogate too.

Resources