{"id":23732090,"url":"https://github.com/mindscapehq/raygun4apple","last_synced_at":"2025-10-08T01:56:01.042Z","repository":{"id":45100812,"uuid":"142387880","full_name":"MindscapeHQ/raygun4apple","owner":"MindscapeHQ","description":"Raygun4Apple provider supporting iOS, tvOS and macOS.","archived":false,"fork":false,"pushed_at":"2025-06-03T03:27:22.000Z","size":90256,"stargazers_count":1,"open_issues_count":0,"forks_count":9,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-09-13T20:15:37.883Z","etag":null,"topics":["breadcrumbs","crash-reporting","debugging-tool","error-handling","error-monitoring","error-reporting","exception-handling","exception-reporting","ios","macos","objective-c","raygun","swift","tvos"],"latest_commit_sha":null,"homepage":"https://raygun.com/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MindscapeHQ.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-07-26T04:17:13.000Z","updated_at":"2025-06-03T03:26:09.000Z","dependencies_parsed_at":"2024-05-28T06:26:27.304Z","dependency_job_id":"4828d774-35d1-4a0d-ad0f-b70ef34de51a","html_url":"https://github.com/MindscapeHQ/raygun4apple","commit_stats":{"total_commits":406,"total_committers":8,"mean_commits":50.75,"dds":"0.10098522167487689","last_synced_commit":"6f629551d81bebc5985b2529d649897511a58e42"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/MindscapeHQ/raygun4apple","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MindscapeHQ%2Fraygun4apple","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MindscapeHQ%2Fraygun4apple/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MindscapeHQ%2Fraygun4apple/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MindscapeHQ%2Fraygun4apple/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MindscapeHQ","download_url":"https://codeload.github.com/MindscapeHQ/raygun4apple/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MindscapeHQ%2Fraygun4apple/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278877088,"owners_count":26061380,"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-07T02:00:06.786Z","response_time":59,"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":["breadcrumbs","crash-reporting","debugging-tool","error-handling","error-monitoring","error-reporting","exception-handling","exception-reporting","ios","macos","objective-c","raygun","swift","tvos"],"created_at":"2024-12-31T04:14:01.770Z","updated_at":"2025-10-08T01:56:01.012Z","avatar_url":"https://github.com/MindscapeHQ.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Raygun4Apple\n\n[Raygun](https://raygun.com/) provider for iOS, tvOS \u0026 macOS supporting Crash Reporting and Real User Monitoring.\n\nOfficially Supports:\n\n- iOS 12+\n- tvOS 12+\n- macOS 12+\n\nNote: raygun4apple may work with earlier OS versions, however we recommend updating to the versions we build and test for to avoid experiencing any unexpected issues.\n\n## Installation\n\n### Using the Swift Package Manager\n\n#### From Xcode\n\n1. Choose `File \u003e Add Package Dependencies…`\n2. In the Search field on the top right, enter the Github URL for raygun4apple: `https://github.com/MindscapeHQ/raygun4apple.git`\n3. Click \"Add Package\", then choose your project under the \"Add to Target\" section. Click \"Add Package\" again.\n\n![A screenshot showing the installation of Raygun inside Xcode](install-preview.png)\n\nYou're now ready to [configure the client](#using-raygun).\n\n#### OR: Manually\n\nIf you're not using Xcode to manage your packages, you can instead update your Package.swift file to include raygun4apple as a dependency.\n\nHere is an example of a macOS CLI application which uses raygun4apple as a dependency:\n\n```swift\nimport PackageDescription\n\nlet package = Package(\n    name: \"macos-cli\",\n    dependencies: [\n        //Note - the version must be atleast 2.0.0 as this is earliest release of this package through SPM.\n        .package(url: \"https://github.com/MindscapeHQ/raygun4apple.git\", from: \"2.0.0\"),\n    ],\n    targets: [\n        .executableTarget(\n            name: \"macos-cli\",\n            dependencies: [\"raygun4apple\"])\n    ]\n)\n```\n\n### With CocoaPods\n\nTo integrate Raygun using CocoaPods, update your Podfile to include:\n\n```bash\npod 'raygun4apple'\n```\n\nOnce updated, you can run `pod install` from Terminal.\n\n### With GitHub releases\n\nThe latest release can be found [here](https://github.com/MindscapeHQ/raygun4apple/releases). The frameworks are attached to each release as a zipped file. This can be downloaded, unzipped and included in you project directory.\n\nOnce included, go to your app's target **General** settings and add the raygun4apple framework to the **Frameworks, Libraries, and Embedded Content** section. Ensure that the framework is set to **Embed \u0026 Sign**.\n\n## Using Raygun\n\n### Swift\n\nTo use Raygun, import the package in your Swift file. Here is an example which imports raygun4apple, initializes the provider, and sends a test exception. Be sure to replace `YOUR_API_KEY_HERE` with your API key from your Application Settings screen in Raygun.\n\n```swift\nimport raygun4apple\n\nlet raygunClient = RaygunClient.sharedInstance(apiKey: \"YOUR_API_KEY_HERE\")\nraygunClient.enableCrashReporting()\nraygunClient.send(exception: NSException.init(name: .genericException, reason: \"This is an exception from Raygun4Apple!\"))\n```\n\nNB: If you recieve a `A server with the specified hostname could not be found` error, you may need to [enable outbound connections for your app](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_network_client). Choose your project target in the left-hand navigator, then choose the \"Signing \u0026 Capabilities\" tab, and check the `Outgoing Connections (Client)` in the \"App Sandbox\" section.\n\n#### Swift UI\n\n_You might like to check our our [Swift UI example app](https://github.com/MindscapeHQ/Raygun4SwiftUI-ExampleApp)_\n\nYou likely want to start Raygun in your `AppDelegate`. By default newer Swift UI apps do not come with an `AppDelegate`, so you can [follow these instructions](https://www.hackingwithswift.com/quick-start/swiftui/how-to-add-an-appdelegate-to-a-swiftui-app) to add one to your project (for macOS you need to [use NSApplication](https://stackoverflow.com/questions/71291654/swiftui-appdelegate-on-macos) instead)\n\nOnce you've done that, your `AppDelegate.swift` should look something like this:\n\n```swift\nimport Foundation\nimport UIKit\nimport raygun4apple\n\n\nclass AppDelegate: NSObject, UIApplicationDelegate {\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -\u003e Bool {\n\n      let raygunClient = RaygunClient.sharedInstance(apiKey: \"YOUR_API_KEY_HERE\")\n      raygunClient.enableCrashReporting()\n\n      return true\n    }\n}\n```\n\nYou are now tracking crashes across your application, and can report manually using the `RaygunClient.sharedInstance()`, for example:\n\n```swift\nRaygunClient.sharedInstance().send(exception: NSException.init(name: .genericException, reason: \"This is an exception from Raygun4Apple!\"))\n```\n\n#### Identifying customers\n\nBy default, each user will be identified as an anonymous user/customers. However you can set more detailed customer information with the following snippet.\n\n```swift\nRaygunClient.sharedInstance().userInformation = RaygunUserInformation.init(\n    identifier: \"123\",\n    email:      \"ronald@raygun.com\",\n    fullName:   \"Ronald Raygun\",\n    firstName:  \"Ronald\",\n    anonymous:  false,\n    uuid:       UUID().uuidString\n)\n```\n\n(More initializers are provided on `RaygunUserInformation` should you want to omit some parts of this information)\n\nNow your crashes will be tracked as affecting this user in Raygun Crash Reporting:\n\n![Screenshot showing affected users in the Raygun Crash Reporting Dashboard](affected-user-example.png)\n\n### Objective-C\n\nIn your AppDelegate class file, import the header for your target platform.\n\n```objective-c\n#import \u003craygun4apple/raygun4apple_iOS.h\u003e\n```\n\nInitialize the Raygun client by adding the following snippet to your AppDelegate application:didFinishLaunchingWithOptions method:\n\n```objective-c\n[RaygunClient sharedInstanceWithApiKey:@\"_INSERT_API_KEY_\"];\n[RaygunClient.sharedInstance enableCrashReporting];\n[RaygunClient.sharedInstance enableRealUserMonitoring];\n[RaygunClient.sharedInstance enableNetworkPerformanceMonitoring]; // Optional\n```\n\n## Sending a test error event\n\nTo ensure that the Raygun client is correctly configured, try sending a test crash report with the following snippet.\n\n```objective-c\n[RaygunClient.sharedInstance sendException:@\"Raygun has been successfully integrated!\"\n                                withReason:@\"A test crash report from Raygun\"\n                                  withTags:@[@\"Test\"]\n                            withCustomData:@{@\"TestMessage\":@\"Hello World!\"}];\n```\n\n## Set up Customers\n\nBy default, each user will be identified as an anonymous user/customers. However you can set more detailed customer information with the following snippet.\n\n```objective-c\nRaygunUserInformation *userInfo = nil;\nuserInfo = [[RaygunUserInformation alloc] initWithIdentifier:@\"ronald@raygun.com\"\n                                                   withEmail:@\"ronald@raygun.com\"\n                                                withFullName:@\"Ronald Raygun\"\n                                               withFirstName:@\"Ronald\"];\nRaygunClient.sharedInstance.userInformation = userInfo;\n```\n\n## Custom Error Grouping\n\nYou can provide your own grouping key if you wish. We only recommend this if you're having issues with errors not being grouped properly by Raygun's default logic.\n\nThe `groupingKeyProvider` is a block (or closure in Swift) that you set on the `RaygunClient.sharedInstance`. This block is called when an error report is being prepared and it receives a `RaygunMessageDetails` object. This object contains all available information about the error, including the error message, class name, tags, custom data, user information, and the detailed thread (stack trace) information.\n\nYour block should return an `NSString` (or `String` in Swift) that will be used as the grouping key. If you return `nil` or an empty string, Raygun will revert to its default grouping logic for that error.\n\n**Important Note on Stack Traces:**\nInside the `RaygunMessageDetails` object:\n\n- `details.error.stackTrace` (a simple array of strings) might be `nil`, especially for reports originating from crashes (KSCrash).\n- `details.threads` (an array of `RaygunThread` objects, each containing `RaygunFrame` objects) provides the rich, structured stack trace information for all reports, including crashes. If your custom grouping logic needs to inspect stack frames, you should use `details.threads`.\n\n### Objective-C Example\n\n```objective-c\n#import \u003craygun4apple/raygun4apple.h\u003e // Or your specific platform import\n\n// In your AppDelegate or relevant setup code:\nRaygunClient.sharedInstance.groupingKeyProvider = ^NSString * _Nullable(RaygunMessageDetails * _Nonnull details) {\n    // Example: Group by the error's class name and the first line of the error message.\n    NSString *className = details.error.className ?: @\"UnknownClass\";\n    NSString *messageSummary = @\"NoMessage\";\n\n    if (details.error.message != nil \u0026\u0026 details.error.message.length \u003e 0) {\n        NSArray\u003cNSString *\u003e *lines = [details.error.message componentsSeparatedByString:@\"\\n\"];\n        if (lines.count \u003e 0) {\n            messageSummary = lines[0];\n        }\n    }\n\n    // You could also inspect details.threads for stack trace information if needed.\n    // For example, to get the class and method of the top-most application frame.\n\n    return [NSString stringWithFormat:@\"%@|%@\", className, messageSummary];\n};\n```\n\n### Swift Example\n\n```swift\nimport raygun4apple\n\n// In your AppDelegate or relevant setup code:\nRaygunClient.sharedInstance().groupingKeyProvider = { details in\n    // Example: Group by the error's class name and the first line of the error message.\n    let className = details.error?.className ?? \"UnknownClass\"\n    var messageSummary = \"NoMessage\"\n\n    if let errorMessage = details.error?.message, !errorMessage.isEmpty {\n        messageSummary = errorMessage.components(separatedBy: \"\\n\").first ?? \"\"\n    }\n\n    // You could also inspect details.threads for stack trace information if needed.\n    // For example, to get the class and method of the top-most application frame.\n\n    return \"\\(className)|\\(messageSummary)\"\n}\n```\n\nThis allows you to customize how errors are grouped together in the Raygun dashboard based on any data present in the `RaygunMessageDetails`.\n\n## Documentation\n\nFor more information please visit our public documentation [here](https://raygun.com/documentation/language-guides/apple/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmindscapehq%2Fraygun4apple","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmindscapehq%2Fraygun4apple","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmindscapehq%2Fraygun4apple/lists"}