I want to trigger some analytics code every time a user in my iOS app moves to a new screen.
Is there a way to detect every call to viewDidAppear, or do I need to implement this in every ViewController ?
Yes, lots of the analytics suppliers frameworks offer this feature. Generally they're implemented with swizzling, so they replace the UIViewController implementation to capture the analytics and then call the stock implementation. As all your view controllers should call super then their code will be run.
It's also possible that you could create a superclass for all your view controllers but this is harder to fit into most apps.
I did something similar to one of my apps with google analytics. At that time I had to subclass my controllers from GAITrackedViewController. That pretty much did it. I added the self.screenName = #"some screen name"; on viewDidAppear method just to know where the user was on my GA Dashboard.
It was explained on the GA docs, so it won't be hard to find.
Related
I'm transitioning from Google Analytics to Firebase Analytics. Unlike Google Analytics, Firebase automatically tracks screen views, which is great! But, instead of tracking the screen, it continuously attempts to track the UINavigationController. I get the following error log twice every time I navigate to a different view controller.
[Firebase/Analytics][I-ACS031006] View controller already
tracked. Class, ID: UINavigationController, -1770652405567491888
Is there some configuration required when you have a navigation controller? How do I get automatic screen tracking working in this scenario?
UPDATE: I haven't found a solution to this yet, but I at least found the cause of the problem. It looks like Firebase doesn't understand your view controller hierarchy if your initial view controller is a Tab Bar Controller. My initial view controller in my main story board is a Tab Bar Controller. If I take this out, I get good screen tracking reporting from my app.
UPDATE: It looks like I've found an OK solution to this, but I'm still wondering if someone has a better idea. Since Firebase sees all of the view controllers under my Tab Bar Controller as the same UINavigationController, I can call setScreenName manually in viewDidAppear for all of them.
Analytics.setScreenName(screenName, screenClass: screenClass)
This is OK because it's not any worse than Google Analyics, but it's not ideal because the system still tries to track the UINavigationController twice for every view controller and I'm also not getting the benefit of automatic screen tracking. I looked into trying to remove the Tab Bar Controller from Firebase as some folks seem to have done, but it looks like those methods have been removed from the current (v4.0.0) version of the Firebase SDK.
Screen is automatically tracked in Google Analytics for Firebase. You can see it in the user engagement card in the Main dashboard. This has been introduced in Firebase Version 3.8.0 for iOS. More in track screen doc. Quoting from the doc:
Events that occur on these screens are automatically tagged with the parameter firebase_screen_class (for example, menuViewController or MenuActivity) and a generated firebase_screen_id. If your app uses a distinct UIViewController or Activity for each screen, Analytics can automatically track every screen transition and generate a report of user engagement broken down by screen.
However, you can also track screens manually using the setCurrentScreen() method. The details on this screen should be available in the user engagement card when you select the ScreenName from the dropdown, all the screens manually tracked in the code should be displayed there with the breakdown of duration on average.
Please note that the setScreenName is not an event, it is rather an event parameter that goes with the event that is tracked in the logEvent() method call.
I have small problem with NSURLSessionDownloadTask, i.e., in my app user can download movies(nearly 1 Gb), if the user click Pause button and get back to the previous viewController then again he wants to resume the download the downloaded percentage goes to 0. Can anyone please tell how to declare that in AppDelegate.m, or else tell how to resume that video from any viewController and After re-launch that app...
thanks in Advance...
Welcome to SO. In general if you have a specific problem you should provide enough code from your project so your readers understand what you are doing now.
In your case we need information on how your view controllers are linked.
What I would suggest for you is to create a separate download manager singleton class. Set it up with a delegate. Define a delegate protocol that lets you get progress updates on the download percentage. Also implement a pause method.
Both your view controllers would reference the singleton.
If you need to manage multiple downloads from different client objects at the same time then your design becomes more complicated. In that case you might want to look at third party libraries like AFNetworking. They handle a lot of this sort of thing for you.
I am creating an iOS8 application and started to implement iAd's Banner in code, but yesterday I discovered that I can use the canDisplayBannerAds property. I enabled it on each of the views in my application, and it is working. Previously, when I was implementing it with my own code, there was a lot of discussion about the importance of using a singleton of the ADBannerView. Does canDisplayBannerAds use a singleton, or is it violating what I had read about the importance of using a singleton? Does it really matter from a performance, advertising, and Apple Store perspective?
Thank you for your comments and feedback,
Mike
No, it uses a new one each time. I ran into that problem when first using iAd. Each vc had canDisplay... And the ads got all messed up. In fact they didn't even show up in the App Store version. Best to use either the singleton method or something similar that reuses the iAd. I myself use the app delegate. All my apps use that and I have not run into any problems at all. Good luck!
EDIT#1
Here is a link to a blog post I wrote using iAd with the app delegate. It is written in Objective-C but at least you will get the general idea. I basically create an iAd banner in the app delegate and then use that one in every vc you need.
It seems like the fade animation between the launch screen and my first view is really slow.
I don't think it used to be like that. Is there a way to control the speed of that transitional animation?
I looked at some apps on my phone and the launch screen doesn't fade as slowly as mine. What things could I have done to affect that?
(No I don't have slow animations turned on, only the fade animation is slow)
In WWDC 2012 video iOS App Performance: Responsiveness they enumerate a whole list of issues that have impact on the app startup time, ranging from attaching to unnecessary frameworks, optional linking to frameworks that you really could make required, the use of static initializers, overly complicated initial scenes, too much information stored in preferences, etc.
That video covers a range of topics, like the above, which impact startup time. In the demonstration, they show how one might benchmark the startup time. Unfortunately, in my experience, there's a good chance that you might not be able to do anything to fix this issue (e.g. you need certain features and therefore need certain frameworks), but it's still an illuminating video and it might give you some ideas of things you can try to alleviate the start-up performance issues.
If your app splash screen show more time, so please check following things in your app.
1. AppDelegate.m
in didFinishLaunchingWithOptions method have you called any heavy method which takes more time for finish task if yes then change that method location, basically in appDelegate class don't write any heavy methods.
2. first view of your app.
check viewDidLoad() method, if you call many method or any heavy method from here then your launch image will show still your control not come out from viewDidLoad method, so if you want call any methods at view launch time then call them from viewWillAppear or viewDidAppear method (in viewDidAppear method don't call any UI related methods)
I never figured out what was going on here, but the next day when I started up xCode and the simulator it was back to the normal loading time.
In iOS 7, ADBannerView no longer needs to be created manually. Instead, they can be requested with a simple self.canDisplayBannerAds = YES;
Now, I cannot set my View Controller as the banner delegate because there is no banner for me to access (to my knowledge).
I need to know when the banner is tapped and when that action is dismissed so I can properly pause/start my Sprite Kit game.
How am I supposed to have these delegate methods called so I can properly respond to the user's actions?
AFAIK, there is nothing in the UIView Controller iAD Additions that explains how to set the delegate for the banners.
Do I need to create the banners manually, or is there a way to achieve this while still using the newer API's?
Unfortunately, if you want to use the delegate methods, you will need to set up your iAd Banner manually. Even if you make your vc the delegate, by just using self.canDisplayBannerAds = YES, will not call the methods you need. In my sprite kit game, I made all the banners manually so I could take care of pausing the game and going to the background. Making them give you the control you are looking for. Good luck.