I've implemented the new Google Analytics library (2.0) for iOS for app tracking. Tracking views etc is very simple, but I'm having trouble understanding how to use Dimensions and Metrics.
I've read the documentation multiple times but I'm having trouble wrapping my head around it.
Basically, I want to check how many of my users have a specific setting enabled when using the app.
In semipseudo-code, this is what I'd like to do:
- (void)applicationLaunched
{
id<GAITracker> tracker = [[GAI sharedInstance] trackerWithTrackingId:#"My ID"];
if (_mySettingIsEnabled) {
[tracker setUserValue:#"Enabled" forKey:#"My Setting"];
} else {
[tracker setUserValue:#"Disabled" forKey:#"My Setting"];
}
}
Can anyone explain to me how I would do this per user with Dimensions and Metrics?
Check the official documentation: https://developers.google.com/analytics/devguides/collection/ios/v2/customdimsmets
Make sure you have a new property (GA is organized in Account/Property/Profiles, so click on the "home", than an account, than add a new app property) - I had an older property/profile and nothing was working with the IOS GA library 2.0.
Register on the GA web, open a Property, there will be a tab for Custom Definitions, where you can register custom dimensions and metrics - Lets say "AppMode", which is the custom definition with index 1.
Set the custom dimension/metric value in your code:
NSString *appMode = #"Demo";
[_gaiTracker setCustom:1 dimension:appMode];
Basically, you might go with custom variables.
Having a specific setting enabled might either be on user or on session level, so you should set the scope to either 1 or 2. The setting you want to track is value of your custom var or the "dimension", and depending on the scope you get the metrics # of users or # of visits automatically.
in JS that looks like
_gaq.push(['_setCustomVar',
1, // This custom var is set to slot #1. Required parameter.
'My Setting', // The name of the custom variable. Required parameter.
'Disabled', // The value of the custom variable. Required parameter.
// (possible values might be Free, Bronze, Gold, and Platinum)
1 // Sets the scope to visitor-level. Optional parameter.
]);
Related
We use the base repo "Roomle UI" based on the "Roomle Web SDK". We are currently customizing this and integrating it into our website accordingly. We would like to deactivate the automatic "zoom in" via scrolling. It interrupts the intended user flow. Unfortunately we haven't found a way to implement this yet without keeping the classic functionality like drag n drop.
Do you guys have any suggestions to handle this?
Currently that's not possible. Please create a feature request here: https://roomle.atlassian.net/servicedesk/customer/portal/4/group/5/create/24
What you could try (but be aware that this relies on private apis and those apis can break at any time in the future) is the following:
!!Warning the next snippet changes private apis!!
window.deactivated = true;
var oldOnMouseWheel = RoomleConfigurator._sceneManager._cameraControl._inputManager._onMouseWheel.bind(RoomleConfigurator._sceneHelper._cameraControl._inputManager);
RoomleConfigurator._sceneManager._cameraControl._inputManager._onMouseWheel = function () {
console.log('!!!!WARNING WE CHANGED A PRIVATE METHOD!!!!');
if (window.deactivated) {
return;
}
oldOnMouseWheel(...arguments);
};
And then to active/deactive you just would need to set window.deactivated to true or false.
But as a reminder, those are private apis which will break eventually
I am looking to split up my user base to 10 group and show 10 different UI and see how they feel about it.
so each user group will have single type of UI always.
i.e Let's say I have 10k users and when I roll out my next release when user install I will be showing for 1000 user 1 UI and for another 1000 user 1 UI like all 10K users.
I know this can be done with the help of AB testing framework.
Basically I want to call one API at the launch of app and it has to return value between 1 to 10 then I can store it in my keychain and next time when app is launched I will see if it's already there in keychain and I will not call the API.
So basically the API will know how many requests has come and it'll divide and send right values back
so based on value in keychain I will show different , different UI and here AB testing framework's job would be giving me value 1 to 10 the API part.
There are so many AB testing framework available online.But I couldn't find any framework that suits my needs.
any help is appreciated !
The best approach would be splitting the users into groups in data base and let login API or some other API return some flag to indicate what group each user belongs to and you can show UI accordingly.
But if that's not possible
Then the simplest approach would be generating a random number between 1-10 and keeping it in keychain and showing a particular UI for it so that next time when you launch the app you can look out for the value in Keychain and if its not there then you can create a new random value and store it in the keychain.This way you will show the same UI for that user always.
This splitting approach is not 100% accurate but its close enough I would say
arc4random_uniform
- (NSInteger)randomNumberBetween:(NSInteger)min maxNumber:(NSInteger)max
{
return min + arc4random_uniform((uint32_t)(max - min + 1));
}
if you take sample of these random numbers 10000 times, you can see each number coming 900-1000 times which is 9-10% and its close enough
for(int i=0;i<10000;i++){
NSLog(#"random:%ld",[self randomNumberBetween:1 maxNumber:10]);
}
Seconds of Current time
you can take the seconds of current date and time and if the second is between 1-6 then you can save value 1 in keychain and for 7-12 you can save value 2 in keychain etc..54-60 you can keep value 10 in keychain.
Others
you can consider splitting the users based on Geography or country or timezone and doing this also has its own pit falls.
Like this you can devise your own strategy to split the user
but if none of the suggestions above fits your criteria then the best approach would be to look for third party AB testing frameworks but If it's going to be implemented in enterprise scale they might charge some money for it.
If I come across any such framework that provides this particular functionality alone as you asked I would update it here.
I would like to attribute the credit of this answer to this post as he has pointed out FireBase Remote Config and A/B testing.
As questioner asked I will explain the steps involved in that to achieve it.
Configuration on server
Visit https://console.firebase.google.com/ and sign in with your
google account.
Choose Create project and Click iOS
Key in app id and nick name and click register app
It'll show a link to GoogleService-Info.plist download then drag & drop it in the project
Choose Next
It'll show you Run your app to verify installation you can choose skip this step
Choose remote config from the landing page
Choose Add variable and enter a variable name of your choice but I enter ABTestVariationType and leave value empty and choose Publish changes
Choose A/B testing from the side bar then click Create Experiment then Choose Remote config
In the upcoming pop up Enter the name of your choice I enter as A/B test POC enter some description about it and that's optional anyway
In the the target users choose your app id and in the percentage of target users choose 100% and click Next then it'll show the variants section
In the variants section there will be a general category named Control group with 50% loaded by default and a variant box with 50% filled in and empty box and you can enter any name in that but I would enter variant 2.Now click add a parameter 8 times now you can see each variant has 10% and name all the variants and I would name variant 3,variant 4 to variant 10.
In the same variants section click Add Parameter from Remote config
Now you can see the a box appearing besides each variation parameter.You can enter unique value to identify each flavour.I would enter value 1 for the first variant and 2 for the second variant like that I will finish up with value 10 for the last variant and click Next
Then goal section appears you can choose one of it but I would choose Retention(15+) days and click Review and click start experiment and in prompt that's appearing choose start again
Integrating in the app
Add the following pods in your project
pod 'Firebase/Core'
pod 'Firebase/RemoteConfig'
Drag and drop the GoogleService-Info.plist that was downloaded during the server configuration
Initiate the firebase with following boiler-plate code
#import Firebase;
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions(NSDictionary *)launchOptions
{
[FIRApp configure];
return YES;
}
4.Have the class RcValues which is another boiler-plate code in your project
#import "RcValues.h"
#import Firebase;
#implementation RcValues
+(RcValues *)sharedInstance
{
static RcValues *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[RcValues alloc] init];
});
return sharedInstance;
}
-(id)init{
self=[super init];
if(self)
{
[self AcivateDebugMode];
[self LoadDefaultValues];
[self FetchCloudValues];
}
return self;
}
-(void)LoadDefaultValues
{
[FIRRemoteConfig.remoteConfigsetDefaults:
#{#"appPrimaryColor":#"#FBB03B"}];
}
-(void)FetchCloudValues
{
NSTimeInterval fetchInterval=0;
[FIRRemoteConfig.remoteConfigfetchWithExpirationDuration:
fetchInterval completionHandler:^(FIRRemoteConfigFetchStatus
status, NSError *_Nullable error)
{
NSLog(#"error:%#",error);
[FIRRemoteConfig.remoteConfig activateFetched];
}];
}
-(void)AcivateDebugMode{ //
FIRRemoteConfig.remoteConfig.configSettings=debugSettings;
FIRRemoteConfigSettings *config = [[FIRRemoteConfigSettings alloc] initWithDeveloperModeEnabled:YES];
FIRRemoteConfig.remoteConfig.configSettings=config;
}
#end
5.Invoke the class in appdelegate didFinishinglaunchoptions
RcValues *Obj=[RcValues sharedInstance];
This will download the keyvalue for ABtesting
6.Use the below code to get the AB testing key from firebase to your app
self.flavourNumber.text=[FIRRemoteConfig.remoteConfig
configValueForKey:#"ABTestVariationType"].stringValue;
Based on the key value you can show different UI as you wish.
Firebase will take care of sending the right value and you don't have to worry about divide the users into groups by yourself.
P.S
Please follow the below tutorials for more detailed info this is just a summary and I will try to summarise or add more pictures when I have free time to make it for easier understand if possible I will try to add sample project in github and link it here
firebase-tutorial-ios-ab-testing
firebase-remote-config-tutorial-for-ios
Imagine changing fonts, colour or some values in your iOS app without submitting a new build. It's pretty easy using Remote config. This tutorial will teach you A/B testing, but before A/B testing I would recommend you to look around Remote Config.
Both of these commands register as analytics events but I can't see a breakdown of the custom event names.
PFAnalytics.trackEventInBackground("ML Feeling Bad", block: nil)
--
var dictionary = ["test" : "val"]
PFAnalytics.trackEventInBackground("ML Feeling Good", dimensions: dictionary, block: nil)
I'm looking at Analytics > Events > Analytics Requests. Custom Breakdown doesn't seem to have any helpful options.
I've just found! Remove the spaces in events names.
For example change "ML Feeling Good" to "MLFeelingGood"
Seems that there is a bug inside Parse Analytics, because events with spaces are displayed in Explorer, but not in Analytics tab. And events with no spaces are displayed correctly.
It takes some time to show Custom event we have registered as pointed out in this link also.
Does it take 24 hours for custom events to be recorded in Parse Analytics
If u want to see your custom event then u can select Analytics > Events > Analytics Requests > Custom Breakdown and then in Custom BreakDown section you have to select read option from the drop down to see your event which u have registered.
Once you have selected read option you must be able to see your event which was Test in my case it is Category and dayType.
Just select your event and turn it on.
I am using
PFAnalytics.trackEvent("video", dimensions:["title": self.title])
with success (and with the mandatory PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions) in the implementation of AppDelegate)
Anyway, in the Parse doc about trackEventInBackground:dimensions:block: they say:
block: The block to execute on server response. It should have the
following argument signature: ^(BOOL succeeded, NSError *error)
So maybe you cannot set the block to nil.
I hope this helps!
I am trying to integrate GooglePlus inside an iOS app of mine.
The app sends a simple message. I have a few questions about the setting of the recipient(s).
Here is the kind of code I am using:
[GPPShare sharedInstance].delegate = self;
id<GPPNativeShareBuilder> shareBuilder = [[GPPShare sharedInstance] nativeShareDialog];
[shareBuilder setPrefillText:#"Hello world! How is everything?"];
[shareBuilder setPreselectedPeopleIDs:#"112233445566778899000"]; // Question point!!
if (![shareBuilder open]) {
NSLog(#"Status: Error (shareBuilder cannot open).");
}
When the line with the comment "Question point!!" is present, I can set one(or a few) individual(s) as recipient(s) of the message.
When it is not present the set of recipients defaults to "Friends".
Here are my two questions:
Is it possible to set one of my circles (or a community) as recipient? Not only "Friends".
When using the "setPreselectedPeopleIDs:" method, one needs the ID of the recipient. How do we find this ID? There are documents and videos on the net showing how to find one's own ID, but since people usually send messages to other peole rather than to themselves, it would also be useful to know how to get other's IDs.
Doesn't seem like you can share with a specific circle.
You can use this method to get all of the visible people in the user's circles using this method
queryForPeopleListWithUserId:collection:
which is outlined here:
https://developers.google.com/+/mobile/ios/people
Explanation of the parameters from the header:
// List all of the people in the specified collection.
// Required:
// userId: Get the collection of people for the person identified. Use "me" to
// indicate the authenticated user.
// collection: The collection of people to list.
// kGTLPlusCollectionVisible: The list of people who this user has added to
// one or more circles, limited to the circles visible to the requesting
// application.
And another question that goes into this a little bit:
How to Fetch Google Plus circles in IOS Sdk
It does not seem to me like you can discern who is in what circle, unfortunately.
Currently, in my AppDelegate, I have an instance variable declared for GNConfig that is set up with all properties I would like to receive.
This instance of GNconfig is used by any class that makes a gracenote request.
The requests I am using are recognition from an audio stream, recognition by local file and a text search which populates an array. The array is then used for track lookups by id for the corresponding array item.
I am able to get all the content I need, except for track and album link data (always returns null).
I have tried plenty of different suggestions and guides with no luck.
Could somebody please help me out? This data is essential to my app and my app is pretty much complete except for this big obstacle.
Thanks in advance.
** edit **
This is in my appDelegate:
_gnConfig = [GNConfig init:#"XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXX"];
[_gnConfig setProperty:#"content.coverArt" value:#"1"];
[_gnConfig setProperty:#"content.coverArt.sizePreference" value:#"LARGE"];
[_gnConfig setProperty:#"content.allowFullResponse" value:#"1"];
I have this in one of my class methods:
NSURL *filePath = [item valueForProperty:MPMediaItemPropertyAssetURL];
[GNOperations recognizeMIDFileFromFile:self config:[[AppDelegate sharedDelegate] gnConfig] fileUrl:filePath];
In the delegate method I have:
gracenoteResponseItem = [result bestResponse];
NSLog("%#", [gracenoteResponseItem trackLinkData]);
Some tracks may not have link data available.
Also if you are doing a local lookup then you will have to set this config option:
[publicProperties setObject:#“1"forKey:#"content.allowfullresponse"];
Unless you have explicitly had your client ID entitled for Link IDs (aka 'external' or '3rd party' IDs), you won't get any in your responses.
By default, Gracenote Open Developer client IDs aren't entitled for any external IDs. You need to coordinate with Gracenote to entitle your client ID to start receiving the desired IDs.