28

Since today extensions run as separated a process I am sure they will not log any crashes out of the box. I assume we need to initialize Crashlytics on the widget separately. E.g. in the viewDidLoad method of the TodayViewController.

  • Is anybody already using Crashlytics inside any iOS / OS X extensions? If so, how did you implemented it?
  • I am also wondering if it would make sense to create a separate app in Crashlytics just for the extension.
Kampai
  • 22,848
  • 21
  • 95
  • 95
martn_st
  • 2,576
  • 1
  • 24
  • 30
  • I haven't been able to use almost anything inside the extensions (Flurry does not work, crashlytics does not work, and even a .h file I have with some asssert macros does not work...) – wolffan Nov 26 '14 at 10:00
  • This is a support question for Crashlytics. Please contact them directly. – Kerni Nov 26 '14 at 10:26
  • @wolffan thats disappointing so far. – martn_st Nov 26 '14 at 10:44
  • @Kerni as far as I know they ask people to create issues here on stackoverflow with their tag. However, I cannot find the quote anymore … so I might be wrong. – martn_st Nov 26 '14 at 10:47

5 Answers5

30

Crashlytics support got in touch with me and provided these steps. I tested them and it now works for me iOS 8 app.

  1. Add the Crashlytics Run Script Build Phase to your extension's target as well (copy / paste the same you added to your main app)

  2. Add the Crashlytics.framework to your extension's linked libraries (e.g. simply check the extension target in its file inspector)

  3. Add the Crashlytics.startWithAPIKey("yourApiKey") to your extension's view controller's initWithCodermethod. (In Apple's today extension template it is called TodayViewController by default)

    > if you have no initWithCoder method yet, it should look like this afterwards:

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        Crashlytics.startWithAPIKey("yourApiKey")
    }
    
Pang
  • 9,564
  • 146
  • 81
  • 122
martn_st
  • 2,576
  • 1
  • 24
  • 30
  • 1
    Forgot to mention: Since every extensions needs to have it's own bundle id, Crashlytics create a separate app in the dashboard on its own anyway. – martn_st Nov 26 '14 at 16:49
  • This fails 50% of the time for me. It may be a problem with multiple extensions (Today and Watch). Basically, I need to rebuild my project all the time because it fails due to Crashlytics not finding the dSYM about every other time. – cyphers Jun 04 '15 at 19:23
  • How can it be? I do `Fabric.with([Crashlytics.self])` inside `init(coder aDecoder: NSCoder)`, it says `[Fabric] [Fabric +with] called multiple times. Only the first call is honored, please pass all kits you wish to initialize` – Oleksii Nezhyborets Aug 05 '17 at 12:27
  • Does `Crashlytics` call `CrashlyticsDelegate` when a previous crash occurred on an app extension? https://stackoverflow.com/q/61801745/9636 – Heath Borders May 14 '20 at 15:53
8

Here is Twitter's own guide to implementing it:

https://twittercommunity.com/t/integrate-fabric-crashlytics-with-ios-8-extension/28905

So, copy the libraries, for instance if you're using CocoaPods you can add Fabric and Crashlytics to the Extension target:

In Podfile:

target :TodayExtension do
  pod 'Fabric'
  pod 'Crashlytics'
end

and run pod install. And don't forget to set Build Active Architecture Only to NO, or you may get linker errors

Then in your TodayViewController:

#import <Fabric/Fabric.h>
#import <Crashlytics/Crashlytics.h>

...

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    [Fabric with:@[CrashlyticsKit]];
    return self;
}

and copy the Fabric Run Script in build phases to your Today Extension target, and copy the Fabric entry from the info plist from the main application into your Today Extension's info plist

andrrs
  • 2,289
  • 3
  • 17
  • 25
6

Here is official how-to described how to use Crashlytics in iOS Extensions:

  • Add this line to your viewController's initWithCoder method Fabric.with([Crashlytics.self])
  • Copy the "Fabric" Dictionary from your main app's Info.plist and paste into your extension's Info.plist.
  • Copy/paste the Run Script Build Phase from your main app's target into your extension's Run Script Build Phase.

And... you good to go!

Valentin Shergin
  • 7,166
  • 2
  • 50
  • 53
  • 1
    Another pitfall: You have to enable Answers in the Fabric dashboard for the extension. Don't know if that information is part of the above linked how-to, since I am greeted with "Sorry, you don't have access to that topic!" when I follow the link. – bfx Jun 26 '17 at 10:19
5

Answer from maremmle works also if you want to add Crashlytics to share extensions on iOS 8.0+. Just remember to put[Crashlytics startWithAPIKey:@"apiKey"]; inside init method from your first ViewController.

edulpn
  • 125
  • 1
  • 8
1

Thanks for all instructions, it works fine in my Share Extension.

I did notice that for my Share Extension, the Fabric Answers dashboard did not show actual data for:

  1. Active Users
  2. Median Total Time Spent in App per User

It does for the companion app. So I was wondering how the Answers SDK would determine this. The most logical seems to monitor the UIApplication notifications. Since the Lifecycle of an Extension is related to a ViewController, these UIApplication notifications are not posted. And hence Fabric doesn't know when the Extension is active.

So I implemented the following solution, which provides the above data in the Fabric Dashboard:

  1. In 'viewDidLoad' of the Extensions main ViewController, post UIApplicationDidBecomeActiveNotification which will trigger the start for Fabric.
  2. Prior before closing the Extension (via completeRequestReturningItems:completionHandler: or cancelRequestWithError:) post UIApplicationWillResignActiveNotification. This will trigger the stop for Fabric.

Please note there is a delay between the action on device, and when the data becomes visible in the Dashboard. Especially for Active Users. It takes around 20-30 seconds after the Extension is presented. But when the Extension is closed, it might take up to 5 minutes before the Active Users is decremented.

Martijn
  • 429
  • 4
  • 13