Google Analytics Integration issues - iphone

I am not sure I fully understand the Google Analytics integration. At least, what I read on Google's SDK Page and what I see in reality are not the same.
I've setup the Tracker in my applicationDidFinishLaunching method, with my key.
[[GANTracker sharedTracker] startTrackerWithAccountID:#"UA-xxxxxxxx-1"
dispatchPeriod:30 // SENDS EACH 30 SECONDS.
delegate:self];
NSError *error;
if (![[GANTracker sharedTracker] setCustomVariableAtIndex:1
name:#"iPhone"
value:appVersion
withError:&error]) {
// Handle error here
ALog("Google Analytics Error: %#", error);
}
if (![[GANTracker sharedTracker] trackPageview:#"/app_did_finish_Launching"
withError:&error]) {
// Handle error here
ALog("Google Analytics Error:%#", error);
}
I am using a delegate to ensure that the dispatch is firing, and it is, and each time it says it is successful.
- (void)trackerDispatchDidComplete:(GANTracker *)tracker
eventsDispatched:(NSUInteger)eventsDispatched
eventsFailedDispatch:(NSUInteger)eventsFailedDispatch {
DLog(#"events dispatched: %d, events failed: %d", eventsDispatched, eventsFailedDispatch);
}
Question 1:
I am trying to see this over WIFI, with a proxy I've setup between my iPhone and the web. I see nothing that looks like Google analytics traffic. Should I expect to see anything?
Question 2:
Its been 24 hrs, and I don't see anything on the Google Analytics site. Should I see something? I've had success with this implementation only when I set the dispatchPeriod to 0, and manually call dispatch in the code.
BOOL success = [[GANTracker sharedTracker] dispatch];
But I really don't want to do this in a shipping app version.
What am I doing wrong? Do I need to call dispatch manually? The SDK implied you only call the dispatch if you want to send it manually (without batching the sends). Am I understanding this correctly?
Thanks for your help.
-Yenyi

Well, it takes a long time to update. More than 24 hrs. But it does update. In the end, decided to go with Flurry, the API was just cleaner.

Related

How to correctly provide networking feedback to the user? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
My app retrieves currency exchange rates from a web service using a synchronous NSURLConnection in a background GCD queue, like this:
// This method is called in background queue
- (NSData*)fetchDataWithURLStr:(NSString*)urlStr {
NSData *jsonData = nil;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSURL *url = [NSURL URLWithString:urlStr];
NSURLResponse *response = nil;
NSError *error = nil;
NSURLRequest *request = [NSURLRequest requestWithURL:url];
jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error != nil) {
NSString *errorMsg = nil;
NSInteger ec = [error code];
if (ec == NSURLErrorTimedOut || ec == NSURLErrorCannotConnectToHost) {
errorMsg = #"Data temporarily not available.";
}
// Call on main thread
dispatch_async(dispatch_get_main_queue(), ^{
// Present the error
[self showErrorWithCode:ec title:#"ERROR" message:errorMsg];
});
jsonData = nil;
}
return jsonData;
}
But the problem is often the app tries to fetch data, and the download seems to be running forever and nothing happens. No status updates just nothing. Often my WiFi is just stalled and I must go to Settings, disable and re-enable this. Or internet connectivity of my WiFi router at home is down but the device is connected to WiFi.
What I really want to do is give precise feedback about what exactly is happening on the network right now. For example
"Trying to contact server..."
"Wait... still trying..."
"Your internet seems broken..."
"Trying again..."
"Response received..."
"Downloaded 20%"
"Downloaded 40%"
"Finished!"
Just exact feedback about what is going on.
Someone recommended MKNetworkKit but it just feels as dead, no feedback whatsoever.
Are there solutions to this problem which work for iOS?
EDIT: I have Reachability in place but it does not give me this kind of feedback I want to display during networking. Also, Reachability does not tell me what is going on when there is a WiFi connection but the internet is stalled.
The fundamental problem here is that it is impossible (yes impossible) to give a reliable diagnosis of a network problem based on the information that is available to your app. There are simply too many possible causes, and some of them are simply not distinguishable without knowledge of the actual networks and / or access to other sources of diagnostic information.
U can user Reachability classes.
Here is a sample code which uses this reachability classes, and notifies us which type connection we are using. The sample code is from apple.
Have a look at & implement in the same way.
In order for showing the progress to the user, i suggest to use NSURLConnection from the its delegate methods you can easily get the status of the connection/request.
In one of its delegate it gives error description.
You should use the asynchronous API instead. Using the synchronous API in a separate worker thread/queue is often not the right way to go (see the WWDC'12 videos about those subjects)
A better solution would be to use the newer NSURLConnection API and the +sendAsynchronousRequest:queue:completionHandler: method instead of using sendSynchronousRequest: returningResponse: error:. This way you would avoid blocking your API and be informed when the request fails (either fails starting or fails while running because the network went down etc).
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse*, NSData*, NSError*) {
// Code that will be executed asynchronously
// when the response to the request has been received
}];
// After the call to this method above, the code will continue executing
// WITHOUT WAITING for the network request to have its response.
This way your UI won't "freeze" and the rest of your code will continue to run, so you can, like, show some progress indicator on your views for example, and so on. The code in the completionHandler block will be called asynchronously (independently of the rest of your code) only once the response has arrived.
Moreover, to be informed when the network itself is unreachable (went down, etc), use Reachability for that [EDIT] You seem to do this already as you added in the EDIT of your question, so you should already be informed about that and being able to inform the user in this case)
Tip: you may also use some third party frameworks, like the excellent [AFNetworking(https://github.com/AFNetworking/AFNetworking), that allows you to do much more when sending network requests, like having an Objective-C block of code to be called while the network request is in progress, allowing you to know the progression of the download easily.
Once you have integrated the AFNetworking project in your workspace, you would be able to do stuff like this:
AFHTTPRequestOperation* reqOp = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];
[reqOp setCompletionBlockWithSuccess: ^(AFHTTPRequestOperation *operation, id responseObject)
{
// Code to execute asynchronously when you successfully received the whole page/file requested
// The received data is accessible in the responseObject variable.
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Code to execute asynchronously when you request failed, for example if you have a network error, or received some 404 error code, etc.
progressLabel.text = [NSString stringWithFormat:#"Download error: %#", error];
}];
[reqOp setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
{
// Code to execute periodically each time a partial chunk of data is received
// So that you can update your progression. For example:
progressLabel.text = [NSString stringWithFormat:#"Downloading %.1f%%", (float)totalBytesRead*100.f/totalBytesExpectedToRead];
}];
[reqOp start]; // start the request
// The rest of the code will continue to execute, and the blocks mentioned above will be called asynchronously when necessary.
Here is how i check for internet connection . You need to add the Reachability first .
+ (BOOL) checkNetworkStatus
{
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [reachability currentReachabilityStatus];
return !(networkStatus == NotReachable);
}

iPhone Google Analytics SDK delegate and multiple accounts problem

I am implementing google Analytics SDK in my iPhone application. I had it working with following code:
AppDelegate .m :
[[GANTracker sharedTracker] startTrackerWithAccountID:#"UA-xxxxxxx-1"
dispatchPeriod:10
delegate:nil];
if (![[GANTracker sharedTracker] trackPageview:string withError:&error]) {
NSLog(#"Error happened with google analytics tracking 2, %#", error);
}else {
NSLog(#"OK");
}
In my analytics account I was getting the wanted results. Then I decided (don't ask me why) to try to send my tracking data to 2nd analytics account too. For curious ones: One account is used for web page and iPhone app stats and the other one is supposed to be just for iPhone.
My ingenious plan was to create 1st sharedTracker, dispatch it, stop it and do the same for the second one:
AppDelegate .h:
#interface AppDelegate : NSObject <UIApplicationDelegate, GANTrackerDelegate>
//implementation
AppDelegate .m:
//1st tracking account
[[GANTracker sharedTracker] startTrackerWithAccountID:#"UA-xxxxxxx-1"
dispatchPeriod:10
delegate:self];
if (![[GANTracker sharedTracker] trackPageview:string withError:&error]) {
NSLog(#"Error happened with google analytics tracking, %#", error);
}else {
NSLog(#"1. GAnalytics: OK");
}
[[GANTracker sharedTracker] stopTracker];
//2nd tracking account
[[GANTracker sharedTracker] startTrackerWithAccountID:#"UA-zzzzzzzz-1"
dispatchPeriod:10
delegate:self];
if (![[GANTracker sharedTracker] trackPageview:string withError:&error]) {
NSLog(#"Error happened with google analytics tracking, %#", error);
}else {
NSLog(#"2. GAnalytics: OK");
}
[[GANTracker sharedTracker] stopTracker];
- (void)trackerDispatchDidComplete:(GANTracker *)tracker
eventsDispatched:(NSUInteger)eventsDispatched
eventsFailedDispatch:(NSUInteger)eventsFailedDispatch{
NSLog(#"For the love of Got, why don't you say something?");
}
I added the delegate method in order to get some clue what's being dispatched, and to find out if SDK is making two different requests, but it seems I can't get my delegate method invoked!
Removing the second tracker's code doesn't help either
I also tried putting the dispatch period to 0 (and -1 with manual dispatch call) but I had no luck with this either…
So, my questions are:
how to implement 2 gAnalytics accounts and
how to make my delegate method do what it's supposed to do - get called after dispatch :)
Thanks in advance,
Luka
I started out exactly with the same requirement of being able to post pageviews, events etc onto two different Google Analytics accounts. But the problem is that, [GANTracker sharedTracker] is a singleton object and you always get the same or single instance of the object back, so you cannot really have two instances of the sharedTracker.
Also in your case, where you are trying to see whether the call back method is called, it will not be called because you are calling [[GANTracker sharedTracker] stopTracker] and this will prevent from dispatch of the events to happen. If you comment out that line, your callback method should get called.
If you look in the app directory under Documents, Google analytics stores all the data in a sqlite database called googleanalytics.sql. You can open it and see the tables in it. Go to that directory and type "sqlite3 googleanalytics.sql" and if you know sqlite commands, you can navigate the tables and stuff. None of the tables have a reference to the Account ID, so my guess is that, unless you do some really smart quirks, you cannot really post to two different Accounts.
Google has support for using multiple tracking accounts in the same application, in its iOS SDK v2
See this SO question and my answer there.

How to verify google analytics when you don't have a site attached to an application on the iphone?

How can I verify my google analytics tracking code without having an actual website?
I'm just going to use it for my app tracking (pageviews/events).
If you don't have a website but instead what to track activity inside a mobile application you will need to use the Google Analytics Mobile SDK (http://code.google.com/mobile/analytics/docs/).
I would try creating test code that hits the API with your tracking ID and see if it shows up in the Google Analytics dashboard.
Make sure you init the library with your app's analytics id:
[[GANTracker sharedTracker] startTrackerWithAccountID:#"your-apps-google-analytics-id"
dispatchPeriod:15
delegate:nil];
#if DEBUG
NSLog(#"******* WARNING: ANALYTICS IN DRY RUN MODE! *******");
[[GANTracker sharedTracker] setDryRun:YES]; // DO NOT COLLECT ANALLYTICS
#endif
Track screen views as if they were page hits:
[[GANTracker sharedTracker] trackPageview:#"/Tutorial" withError:nil];
Track event/actions:
[[GANTracker sharedTracker] trackEvent:#"Registration"
action:#"Skipped"
label:nil
value:0
withError:nil];

iPhone App Google Analytics

I am having issues setting up Google Analytics for my iPhone Application. I have a website that I have sucesfully been using Google Analytics on, and so I am pretty familiar with how it works.
I set up a new fake domain with the following formation: myapp.mysite.com. I got the UA ID that was made and used that as shown below.
In my iPhone application's "didfinishlaunching" method, I have the following code:
[[GANTracker sharedTracker] startTrackerWithAccountID:#"UA-XXXXXXXX-X"
dispatchPeriod:kGANDispatchPeriodSec
delegate:nil];
NSError *error;
if (![[GANTracker sharedTracker] trackEvent:#"test" action:#"my_action" label:#"my_label" value:-1 withError:&error]) {
NSLog(#"error ocurred");
}
where UA-XXXXXXXX-X is filled in with my ID.
I install the application on my phone, run the app for over 20 minutes, and google analytics still states that "tracking is not installed."
What is wrong here?
Thanks!
Here are a few things to try:
First, try adding
BOOL success = [[GANTracker sharedTracker] dispatch];
to the end of your code and testing the value of success.
Second, I don't see kGANDispatchPeriodSec defined in GANTracker.h. Is this a const that you're creating? Pass in a 0 as the dispatchPeriod instead so dispatches are sent immediately instead of batched. (You'll want to change this before you submit your app.)
Finally, implement GANTrackerDelegate on your class and see what's happening in the trackerDispatchDidComplete:eventsDispatched:eventsFailedDispatch call. This will tell you if your dispatch calls are failing, but unfortunately won't tell you why.
See this link about adopting a protocol on your class. In your .m file, add the following:
#pragma mark GANTrackerDelegate
- (void)trackerDispatchDidComplete:(GANTracker *)tracker
eventsDispatched:(NSUInteger)eventsDispatched
eventsFailedDispatch:(NSUInteger)eventsFailedDispatch {
NSLog(#"events dispatched: %d, events failed: %d", eventsDispatched, eventsFailedDispatch);
}

Cannot get Google Analytics API to register page views on iPhone

I would like to gather usage statistics for my iPhone app using Google Analytics so I'm trying to configure it using the following tutorial: http://code.google.com/intl/fr-FR/apis/analytics/docs/tracking/mobileAppsTracking.html
I think I did everything they indicate in the documentation, and I get no error on the iPhone side, but I don't see any visits in Google Analytics.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[self initGoogleAnalytics];
//...
}
-(void)initGoogleAnalytics{
[[GANTracker sharedTracker] startTrackerWithAccountID:[[NSBundle mainBundle] objectForInfoDictionaryKey:#"GoogleAnalyticsCode"]
dispatchPeriod:-1
delegate:nil
NSError *error;
if(![[GANTracker sharedTracker] trackPageview:#"/home" withError:&error]){
NSLog(#"%#", [error localizedDescription], nil);
}
[[GANTracker sharedTracker] dispatch];
}
Any idea why this is not working?
this is the same answer that I put at: Problem dispatching with google mobile analytics for iphone
The Google Analytics stop sending data when you try to send a non formatted "URL", if it is not initiated with the "/" or contain some specific chars, it will start only returning errors.
The best thing to do is, verify that you are placing the "/" on the beginning of you URL and before sending, format your URL to avoid any problem, by doing:
NSString* pageURLString = [pageURL stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
Encoding it with NSASCIIStringEncoding, will format the URL properly. The same can be used when tracking an event.