15

Updates

19th August 2015 - Bug seems to have now been fixed in the 3.13 update, even though the only thing they list in their changelog is "Fixed an issue which caused crashes when using setCampaignParametersFromUrl". Take that as you will.

8th June 2015 - Still encountering this problem. If I disable automatic sending of events ([GAI sharedInstance].dispatchInterval = -1;) then I still receive errors. I assume, therefore, that the problem lies with inserting the event into the Google Analytics SQLite database, that somehow my own database statement that is currently in progress are becoming void.

10th June 2015 - Still encountering crashes. Tried removing my controllers extending GAITrackedViewController and sending the createScreenView track manually with no change in crash frequency.

25th June 2015 - Still encountering crashes.


Intro

I have added the Google Analytics SDK 3.12 to my iPhone app and everything is working as expected - I run the app and can see all of the hits and events that I have setup coming through on the Web interface.

I am initialising the SDK in my AppDelegate right at the top of my didFinishLaunchingWithOptions, like so:

[[GAI sharedInstance] trackerWithTrackingId:GOOGLE_ANALYTICS_ID];

The problem

However, I have found that running Google Analytics creates errors when I try and use SQLite for myself. They can manifest as serious errors such as:

  • "Database disk image is malformed" and then insta-crashes
  • "Disc i/O error" whenever I run a query (though doesn't crash)

And they can also cause my own SQLite queries to just fail, for instance:

if (! sqlite3_prepare_v2(_db, [sql UTF8String], -1, &_statement, NULL) == SQLITE_OK) {`
    // ..
    // ..

    if (sqlite3_step(_statement) == SQLITE_ROW) {

Will result, randomly, in the following error:

sqlite3_prepare_v2 EXC_BAD_ACCESS (code=1, address=0x6800000000)

If I comment out the SDK initialisation then everything goes back to being incredibly stable. Uncomment it again and it will crash the app within a minute.


Pre-emptive question answering

  1. Am running this on a iPhone 6 running 8.3 (12F70).

  2. Have tried uninstalling and reinstalling the app.

  3. I have added all of the pre-requisites for Google Analytics to work; all of the .m files to the library, the libGoogleAnalyticsServices.a file, and also the Linked Frameworks and Libraries.

  4. I also have Crashlytics, but have tried commenting it out from the code ([Fabric with:@[CrashlyticsKit]];) and removing its library from the Linked Frameworks and Libraries with exactly the same results.


Code

Setting up the class

// In didFinishLaunchingWithOptions
[Db setup];
[Db connect];

Accesses the class

Db * db = [[Db alloc] init];

if ([db prepare:@"SELECT * FROM `table` WHERE `id` = ?" withBindings:@[@"123"]]) {
    while ([db stepThrough]) {
        // ..
    }
}

[db finalise];

The class

(Have indicated where the errors appear with comments)

@implementation Db

static sqlite3  * _db;
static NSString * _dbPath;

#pragma mark - Setup

+ (BOOL)setup {
    NSString      * sqlBundlePath   = [[NSBundle mainBundle] pathForResource:@"db" ofType:@"sqlite"];
    NSString      * documentsFolder = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString      * sqlDocumentPath = [[documentsFolder stringByAppendingPathComponent:@"db"] stringByAppendingPathExtension:@"sqlite"];
    NSFileManager * fileManager     = [NSFileManager defaultManager];

    if (! [fileManager fileExistsAtPath:sqlDocumentPath]) {
        NSError * error;
        BOOL success = [fileManager copyItemAtPath:sqlBundlePath toPath:sqlDocumentPath error:&error];

        if (! success) {
            return NO;
        }
    }

    _dbPath = sqlDocumentPath;
    return YES;
}

+ (BOOL)connect {
    sqlite3_config(SQLITE_CONFIG_SERIALIZED);
    return sqlite3_open([_dbPath UTF8String], &_db);
}

#pragma mark - Querying

- (BOOL)prepare:(NSString *)sql withBindings:(NSArray *)bindings {
    // ERROR CAN OCCUR ON THE FOLLOWING LINE
    if (! sqlite3_prepare_v2(_db, [sql UTF8String], -1, &_statement, NULL) == SQLITE_OK) {
        NSLog(@"Error whilst preparing query: %s", sqlite3_errmsg(_db));
        sqlite3_finalize(_statement);
        return NO;
    }

    for (int i = 0; i < [bindings count]; i++) {
        sqlite3_bind_text(_statement,
                          i + 1,
                          [bindings[i] isKindOfClass:[NSNull class]] ? [@"" UTF8String] : [bindings[i] UTF8String],
                          -1,
                          SQLITE_TRANSIENT);
    }

    return YES;
}

- (BOOL)stepThrough {
    // ERROR CAN OCCUR ON THE FOLLOWING LINE
    if (sqlite3_step(_statement) == SQLITE_ROW) {
        return YES;
    }

    sqlite3_finalize(_statement);
    return NO;
}

- (void)finalise {
    sqlite3_finalize(_statement);
}

@end
cjhill
  • 1,004
  • 2
  • 9
  • 31
  • Seems that you are doing it the right way. Can you use another platform for analytics? – webo80 Jun 12 '15 at 11:46
  • We would ideally like to use Google Analytics as we also use it for our website, so it will tie in with our conversion goals, etc. – cjhill Jun 13 '15 at 13:41

1 Answers1

0

Upgrading to the new version of the SDK (3.13) fixed this issue (at least for me), even though their changelog does not specifically mention it.

cjhill
  • 1,004
  • 2
  • 9
  • 31