Parse analytics custom event not registering - ios

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!

Related

Multiple user Video Call using WebRTC SDK Directly

Hi I am working on a Video Call Solution by using WebRTC directly. I have achieved 1-1 video call using firebase as Signaling service and using default google ICE Servers.
Core Req: Multiple users with in a Room using WebRTC at least 4 users using the default ice/stun servers available. I'm using pod 'GoogleWebRTC'
Issue comes when multiple users joins the same room ID.
So, I am maintaining Peerconnection reference as this
var peerConnection: RTCPeerConnection! = nil
When a new user i.e., remote user joins I set its description as below
self.peerConnection.setRemoteDescription(offer, completionHandler: {(error: Error?) in
if error == nil {
LOG("setRemoteDescription(offer) succsess")
self.makeAnswer() // Create Answer if setRemoteDescription succeeds
} else {
LOG("setRemoteDescription(offer) ERROR: " + error.debugDescription)
}
})
What I feel ? Issue is when third user joins again I set the remote Description with above mentioned code which makes my previous video stops to render sometimes or most of the times.
I looked for solutions and found need to maintain multiple peer connection references, but how? Any help with my requirement will be appreciated.
Just give me clue or sample code will be really great.
In case of multiple user call you should have multiple peerconnections, because it's isn't possible to set different sdps to one pc.
So you can use something like this
var peerConnectionMap = [String: RTCPeerConnection]()
Where String here is some constant user id.
When new user is joined to the room, then you create new pc and store it in this dictionary. Then you exchange with sdps as usual.
Don't forget that you should reuse local audio-video track created when first peerconnection is created.

How to do simple AB testing in iOS

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.

How many maximum printings can UIPrintInteractionController (Swift) execute?

How many maximum printings can UIPrintInteractionController (Swift) execute?
I'm currently doing AirPrint for a project.
Wondering how to do stress tests of printing in bulk in use of Printer Simulator.
Is there a delegate of something like printInteractionControllerIsPrintingJob?
How to debug a number of printing waiting in queue?
Is there any way to customise the alert view of printing?
Cheers,
From the documentation :
1- var printingItems: [Any]? { get set }
Takes an array of printing-ready objects ( NSURL, NSData, UIImage, or ALAsset). The documentation doesn't cite any limit so we assume the limit would be the value of unsigned int in your architecture.
2- There are 2 delegate methods for the beginning and end of printing :
Start and End of a Print Job
func printInteractionControllerWillStartJob(UIPrintInteractionController)
//Tells the delegate that the print job is about to start.
func printInteractionControllerDidFinishJob(UIPrintInteractionController)
//Tells the delegate that the print job has ended.
You can use those to get the IsPrinting status. (between first and second).
3- The documentation doesn't offer any delegate method to get the waiting in queue
4- You can customise the alert using :
printInfo UIPrintInfo: The aforementioned print job configuration.
printPaper UIPrintPaper: A simple type that describes the physical and printable size of a paper type; except for specialized applications, this will be handled for you by UIKit.
showsNumberOfCopies Bool: When true, lets the user choose the number of copies.
showsPageRange Bool: When true, lets the user choose a sub-range from the printed material. This only makes sense with multi-page content—it’s turned off by default for images.
showsPaperSelectionForLoadedPapers Bool: When this is true and the selected printer has multiple paper options, the UI will let the user choose which paper to print on.
For some detailed explanation about printing using Swift, please refer to the following link:
UIPrint​Interaction​Controller - Written by Nate Cook
If this response was helpful and has what you needed, please don't forget to validate it :).
Good luck with your app.

Non-screenview events with Google Tag Manager on iOS

we're trying to use GTM on iOS to track non-screenview events using the data layer and cannot get this to work. First, here's our call to GTM:
NSLog(#"voted!");
NSLog(#"question: %#, answer: %#",self.question.question,selectedAnswer.answer);
[[ATITracking instance] trackEventWithTagManager:#"didVote" parameters:#{#"questionValue":self.question.question,#"voteValue":selectedAnswer.answer}];
We have 2 data layer variables set in GTM for the questionValue and the voteValue. See:
https://www.dropbox.com/s/jru5a06vs1bfmm3/variables.jpg?dl=0
And here's our trigger with the event set to didVote:
https://www.dropbox.com/s/0ydxml4yemji2f5/trigger.jpg?dl=0
And our event tag uses the trigger from above (cannot post link due to rep limit.)
Has anyone seen a non-screenview event tracked successfully in iOS using GTM? Thanks in advance.
Events are working for me with no problems. This is slightly modified code from the GTM iOS SDK example
-(void) logEvent:(NSString*) event withProperties:(NSDictionary*) properties {
NSMutableDictionary* eventProperties = [NSMutableDictionary dictionaryWithDictionary:#{#"event": #"customEvent",#"eventCategory":#"User action",#"eventName":event}];
if (properties) {
[eventProperties addEntriesFromDictionary:properties];
}
TAGDataLayer* dataLayer = self.tagManager.dataLayer;
[dataLayer push:eventProperties];
}
Based on GTM documentation https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#events event category and event action must not be empty. I didn't see any events in GA until I configured these parameters in my tag and started pushing them from the client.
Hope it helps.
Please see attached screenshot of my tag:

For plug in running on iOS

What I want to implement is as follow:
A-app (calling app) : request the return value of a-string sent as parameter : request(a-string) -> b-string.
B-app (plug-in installed separately by me or others, it plays the role of dictionary or database ) : search a-string from database and return the result (b-string).
With successful experiences of plug-in on android and with Apple's confident rhetoric of plug-in, I thought plug-in, of course, run on iOS. After a lot of hard work, however, I finally found out:
* Note : The creation and use of loadable bundles is not supported in iOS.*
Nonetheless, not giving up, I finally made it with custom URl and pasteboard:
A-app : write a-string and false state to pasteboard & call B-app via custom URL.
B-app : viewDidLoad runs following func and thereafter exit program ; func { read pasteboard and search from database & write the result(b-string) and true state to pasteboard }
A-app : while-loop detects whether state is false or true. if true, catch b-string from pasteboard.
Anyway it works but it's too long thus almost useless. Do you have any idea for better solutions? Why doesn't Apple allow plug-in for iOS? Any responses are welcome. Thank you.
I can't answer why Apple doesn't allow plug-ins, but I can offer some advice on what you're trying to achieve.
The common pattern for sending data back to your application is to implement a callback url, so the A-app would also implement a custom URI and add that to the uri sent to B-app.
B-app would then process the uri as you have already implemented, but then instead of exiting, it simply sends the data you requested in the uri passed to it.
See http://x-callback-url.com for more details and example implementations.

Resources