{"id":13990228,"url":"https://github.com/uber/startup-reason-reporter","last_synced_at":"2025-10-08T03:41:32.169Z","repository":{"id":62456017,"uuid":"89406128","full_name":"uber/startup-reason-reporter","owner":"uber","description":"Reports the reason why an iOS App started.","archived":false,"fork":false,"pushed_at":"2018-07-10T06:15:29.000Z","size":258,"stargazers_count":98,"open_issues_count":5,"forks_count":9,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-09-14T19:51:49.779Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uber.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-25T20:57:20.000Z","updated_at":"2025-07-16T20:45:07.000Z","dependencies_parsed_at":"2022-11-02T00:01:28.446Z","dependency_job_id":null,"html_url":"https://github.com/uber/startup-reason-reporter","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/uber/startup-reason-reporter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fstartup-reason-reporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fstartup-reason-reporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fstartup-reason-reporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fstartup-reason-reporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uber","download_url":"https://codeload.github.com/uber/startup-reason-reporter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fstartup-reason-reporter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278886405,"owners_count":26062973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-09T13:02:29.064Z","updated_at":"2025-10-08T03:41:32.135Z","avatar_url":"https://github.com/uber.png","language":"Objective-C","funding_links":[],"categories":["Objective-C"],"sub_categories":[],"readme":"# Startup Reason Reporter [![Build Status](https://travis-ci.org/uber/startup-reason-reporter.svg?branch=master)](https://travis-ci.org/uber/startup-reason-reporter)\n\nThe Startup Reason Reporter provides developers the reason that an iOS application has launched, or equivalently, the reason that the application terminated on the prior launch.\n\n## Use\n\nUsage is fairly straight-forward:\n\n\nSwift:\n\n```swift\n// Determine whether the app crashed on a prior launch\nlet crashedOnPriorLaunch = ...\n\n// Initialize a storage mechanism implementing UBApplicationStartupReasonReporterPriorRunInfoProtocol\nlet previousRunInfo: ApplicationStartupReasonReporterProtocol = ...\n\n// Initialize the notification relay\nlet notificationRelay = ApplicationStartupReasonReporterNotificationRelay()\n\n// Initialize the startup reason reporter\nlet startupReasonReporter = ApplicationStartupReasonReporter(previousRunDidCrash: crashedOnPreviousLaunch,\npreviousRunInfo: previousRunInfo,\nnotificationRelay: notificationRelay,\ndebugging: false)\n\n// Profit\nlet startupReason =  startupReasonReporter.startupReason\n\n// ...\n// In AppDelegate connect notification relay to app lifecycle methods\n\npublic func applicationDidBecomeActive(_ application: UIApplication) {\n    notificationRelay.updateApplicationStateNotification(Notification(name: .UIApplicationDidBecomeActive))\n}\n\npublic func applicationWillResignActive(_ application: UIApplication) {\n    notificationRelay.updateApplicationStateNotification(Notification(name: .UIApplicationWillResignActive))\n}\n\npublic func applicationWillTerminate(_ application: UIApplication) {\n    notificationRelay.updateApplicationStateNotification(Notification(name: .UIApplicationWillTerminate))\n}\n```\n\nObj-C:\n\n```objc\n// Determine whether the app crashed on a prior launch\nBOOL crashedOnPriorLaunch = ...\n\n// Initialize a storage mechanism implementing UBApplicationStartupReasonReporterPriorRunInfoProtocol\nid\u003cUBApplicationStartupReasonReporterPriorRunInfoProtocol\u003e runInfo = ...\n\n// Initialize the notification relay\nid\u003cUBApplicationStartupReasonReporterNotificationRelayProtocol\u003e = [[UBApplicationStartupReasonReporterNotificationRelay alloc] init]\n\n// Initialize the startup reason reporter\nUBApplicationStartupReasonReporter *startupReasonReporter = [[UBApplicationStartupReasonReporter alloc] initWithPreviousRunDidCrash:crashedOnPriorLaunch\n        previousRunInfo:runInfo\n        notificationRelay: notificationRelay\n        debugging:[UBBuildType isDebugBuild]];\n\n// Profit\nUBStartupReason startupReason = startupReasonReporter.startupReason\n\n// ...\n// In AppDelegate connect notification relay to app lifecycle methods\n\n- (void)applicationDidBecomeActive:(UIApplication *)application\n{\n    [self.notificationRelay updateApplicationStateNotification:[NSNotification notificationWithName:UIApplicationDidBecomeActiveNotification object:nil]];\n}\n\n- (void)applicationWillResignActive:(UIApplication *)application\n{\n    [self.notificationRelay updateApplicationStateNotification:[NSNotification notificationWithName:UIApplicationWillResignActiveNotification object:nil]];\n}\n\n- (void)applicationWillTerminate:(UIApplication *)application\n{\n    [self.notificationRelay updateApplicationStateNotification:[NSNotification notificationWithName:UIApplicationWillTerminateNotification object:nil]];\n}\n```\n\n## Introduction\n\nThe UBStartupReasonReporter is based on the general idea that applications may terminate for a fixed set of reasons on iOS.  \n\nThrough process of elimination, the UBStartupReasonReporter can detect important events such as OOM crashes and app upgrades.  The full list of possible startup reasons is described below.\n\nCritically, the reported startup reason is only as accurate as the the data that is provided to it.  For instance, some crash detection mechanisms may not encompass all forms of crashes, which may throw off the reported reason.  Additionally we found that application state notifications are not always delivered, or given time to execute unless you hook into the first notification emitted by the OS, in the corresponding AppDelegate method. This is why we provide a notification relay to easily hook into these lifecycle events.\n\nOur process for detecting various startup reasons is detailed by Ali Ansari and Grzegorz Pstrucha in this blog post: [Reducing FOOMs in the iOS app](https://code.facebook.com/posts/1146930688654547/reducing-fooms-in-the-facebook-ios-app/)\n\nIn order for detection to work, you must provide a class that implements prior run storage and conforms to UBApplicationStartupReasonReporterPriorRunInfoProtocol.  We provide one such class, backed by the file system using JSON encoding, in UBApplicationStartupReasonReporterPriorRunInfo, though you may also wish to implement your own version that is backed by your preferred storage mechanism.\n\nPossible startup reasons are as follows:\n\n```objc\nUBStartupReason const UBStartupReasonDebug = @\"debug\";\nUBStartupReason const UBStartupReasonFirstTime = @\"first_time\";\nUBStartupReason const UBStartupReasonCrash = @\"crash\";\nUBStartupReason const UBStartupReasonForceQuit = @\"force_quit\";\nUBStartupReason const UBStartupReasonAppUpgrade = @\"app_upgrade\";\nUBStartupReason const UBStartupReasonOSUpgrade = @\"os_upgrade\";\nUBStartupReason const UBStartupReasonBackgroundEviction = @\"background_eviction\";\nUBStartupReason const UBStartupReasonRestart = @\"restart\";\nUBStartupReason const UBStartupReasonOutOfMemory = @\"out_of_memory\";\n```\n\n## Installation\n#### CocoaPods\n\nTo integrate the StartupReasonReporter into your project add the following to your `Podfile`:\n\n```ruby\npod 'StartupReasonReporter', '~\u003e 0.2.0'\n```\n\nTo integrate only the `UBApplicationStartupReasonReporterPriorRunInfoProtocol` protocol, but not the implementation, add the following to your `Podfile`:\n\n```ruby\npod 'StartupReasonReporter/Core', '~\u003e 0.2.0'\n```\n\n#### Carthage\n\nTo integrate the StartupReasonReporter into your project using Carthage add the following to your `Cartfile`:\n\n```ruby\ngithub \"uber/startup-reason-reporter\" ~\u003e 0.2.0\n```\n\n## Contributions\n\nWe'd love for you to contribute to our open source projects. Before we can accept your contributions, we kindly ask you to sign our [Uber Contributor License Agreement](https://docs.google.com/a/uber.com/forms/d/1pAwS_-dA1KhPlfxzYLBqK6rsSWwRwH95OCCZrcsY5rk/viewform).\n\n- If you **find a bug**, open an issue or submit a fix via a pull request.\n- If you **have a feature request**, open an issue or submit an implementation via a pull request\n- If you **want to contribute**, submit a pull request.\n\n## License\n\n    Copyright (c) 2015 Uber Technologies, Inc.\n\n    Permission is hereby granted, free of charge, to any person obtaining a copy\n    of this software and associated documentation files (the \"Software\"), to deal\n    in the Software without restriction, including without limitation the rights\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n    copies of the Software, and to permit persons to whom the Software is\n    furnished to do so, subject to the following conditions:\n\n    The above copyright notice and this permission notice shall be included in\n    all copies or substantial portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n    THE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuber%2Fstartup-reason-reporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuber%2Fstartup-reason-reporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuber%2Fstartup-reason-reporter/lists"}