Giter Site home page Giter Site logo

amplitude-swift's People

Contributors

amplitude-sdk-bot avatar crleona avatar falconandy avatar izaaz avatar justin-fiedler avatar kolyan94 avatar liuyang1520 avatar mercy811 avatar qingzhuozhen avatar ryancrosby-bl avatar slavasemeniuk avatar theolampert avatar yuhao900914 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

amplitude-swift's Issues

Potential issue with cache file location

While evaluating the Amplitude-Swift at work, we've had issues with other project's (unrelated to us) events showing up in our dashboard, we have screenshots demonstrating this, but I don't want to post them here, please let me know if you need to see these.

What it looks like is as if all Mac apps running on a user's machine, with multiple instances of the Amplitude Swift SDK will write their events to the same cache file, which leads to leaking events into other people's dashboards when these are batched. This is tricky to reproduce because it has to happen within a fairly short time window before the events are batched. Because our app is a menu bar app that interacts with other apps, it opens up the possibility of this happening much more frequently.

Expected Behavior

The cache files/folders should be unique per instance.

Current Behavior

All instances of the SDK share a single cache file.

Possible Solution

Create unique cache folders/files per instance.

Steps to Reproduce

Create two separate Amplitude instances with separate API keys and run them at the same time, observe that they both write to the same location, run a debugging proxy or similar to inspect outgoing requests. You'll have to simulate some situation in which both write to the same file within the timeout that batches these requests.

Environment

  • SDK Version: 1.1.0
  • OS Info: N/A

Please let me know if I'm missing something here.

Revenue event

Summary

Hey team, what to pass to revenue event in order to get "Revenue (verified)"?

  1. It's completely unclear from documentation (use string, use id, nothing specific)
  2. Based on old iOS SDK it used to be Data which's converts to base64, in swift - it's string, so, my guess here - receipt should be converted to base64
  3. Old iOS SDK doesn't have receiptSignature, what's to use here? (I tried many different options, since signature could be retreived in der or raw representation)
  4. In that help article (https://help.amplitude.com/hc/en-us/articles/115003116888-Track-revenue) you have a link that to "original in-app purchase verification". So, is StoreKit 2 supported at all?

Events are sent in wrong order or missed?

Summary

Hi! I've been using Amplitude for years and after migrating from Amplitude-iOS to Amplitude-Swift library I see some strange thing in User Events Stream:
As I see some events are in wrong order (Session End is before Session Start). Some days there is only one event (which is impossible without Start Session & End Session).
Do you have any clue what might be the reason?

image

This screenshot was taken from user stream from Unique chart:

image

May this issue correlate with denied iOS 14 App Tracking Alert?

AmplitudeSwift (0.7.3)
AnalyticsConnector (1.0.3)

disableIDFV on tracking options has no effect

Trying to dissable IDFV tracking, has no effect, since the Amplitude initializer set its deviceid as the idfv before the tracking options are even checked.
Initializing the sdk like this:

Amplitude(
            configuration: Configuration(
                apiKey: Constants.ExternalSDKs.Amplitude.apiKey(),
                trackingOptions: TrackingOptions()
                    .disableTrackIpAddress()
                    .disableTrackIDFV()
            )
        )

in the Amplitude initializer the ContextPlugin is initialized:

func initializeDeviceId() {
        var deviceId = amplitude?.state.deviceId
        if isValidDeviceId(deviceId) {
            return
        }
        if deviceId == nil {
            deviceId = staticContext["idfv"] as? String
        }
        if deviceId == nil {
            deviceId = NSUUID().uuidString
        }
        _ = amplitude?.setDeviceId(deviceId: deviceId)
    }

this will set the deviceId on the amplitude instance as the idfv.
Then later even if the event.idfv field will not be filled, the device id will still be equal to the idfv.

Expected Behavior

disabling the idfv tracking should also anonymize the deviceid on the amplitude instance

Current Behavior

amplitude instance device id is still equal to the idfv

Possible Solution

When the ConectPlugin is initialized, the tracking options should be passed down, and when the deviceid is initialized a check should be done, and if idfv is disabled, the device id should be set to a random uuid

Steps to Reproduce

  1. init the sdk with this code:
Amplitude(
            configuration: Configuration(
                apiKey: Constants.ExternalSDKs.Amplitude.apiKey(),
                trackingOptions: TrackingOptions()
                    .disableTrackIpAddress()
                    .disableTrackIDFV()
            )
        )
  1. track any event
  2. the event.deviceid is equal to idfv

Environment

  • SDK Version: 1.1.0
  • OS Info: any iOS

Add the possibility to set the default disk location where to save SDK temporary files

The Amplitude SDK creates an "amplitude" folder inside the app Documents directory and this is ok.

However, because our app needs to expose the Documents folder in the native iOS "Files" app, we would like to avoid exposing the "amplitude" folder too, but we there seems to be no way to change its location from the SDK.

Could it be possible to add such feature in the SDK config?

Termination warning due to background task

Expected Behavior

Background task configured correctly

Current Behavior

I receive such message in console

Background Task 13 119 ("amplitude"), was created over 30 seconds ago.
In applications running in the background, this creates a risk of termination.
Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.

Possible Solution

Not sure, probably call UIApplication.endBackgroundTask(_:) when task is completed

Steps to Reproduce

Just run the app, the logs will come soon. Sample log:
Amplitude.zip
I believe there was no such problem in Amplitude-iOS SDK, only in Swift one.

Environment

  • SDK Version: Amplitude-Swift 1.1.0
  • OS Info: iOS 17.1.1, iPhone 13

Crash in SDK

We are seeing crashes in our app in production from the Amplitude SDK. Unfortunately, there doesn't seem to be a consistent repro. In case it's helpful, we are calling the identify method from a async function.

Crash report:
image

Environment

  • SDK Version: 1.3.6
  • OS Info: iOS 17.3.1

Custom instance name appears to cause issues reconciling past events, causing memory leak and crashes

Expected Behavior

The SDK should be able to manage sending events and flushing the data store properly when using a custom instance name (as recommended here: https://www.docs.developers.amplitude.com/data/sdks/ios-swift/#security).

Current Behavior

When initializing the Amplitude iOS SDK with a custom instance name, the SDK uploads thousands of past events on every app launch, even if no actions are taken in the app and reset() has already been called.

Possible Solution

Removing my custom instance name and using the default configuration seems to have resolved the issue.

Steps to Reproduce

  1. Initialize the SDK with a custom instance name and DEBUG level logging.
  2. Track any number of events.
  3. Restart the app and monitor for old events being uploaded. After 30 seconds, the debugger may warn you that Background Task (123) ("amplitude"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination.
  4. If you've logged enough events and you wait long enough, the app actually will terminate.

Related Amplitude Support Ticket: https://help.amplitude.com/hc/en-us/requests/306102

error-examples-additional-logging.txt
error-logs-example.txt

Environment

  • SDK Version: 1.1.0
  • Device: iPhone X, 2021 MacBook Pro 16-inch M1
  • OS Version: iOS 16.7.5, Mac OS 14.0
Screenshot 2024-02-24 at 5 02 14 PM

Cannot Add Amplitude to Swift Package

Expected Behavior

We are trying to include Amplitude iOS as part of our package.

Current Behavior

It's not getting added when we compile the XCFramework file and is read as a missing dependency.

Steps to Reproduce

  1. Create a SwiftUI Package and Add Amplitude
  2. Try and compile the project into a XCFramework like so
xcodebuild archive \
 -scheme YOUR_PROJECT \
 -archivePath ./device/ \
 -sdk iphoneos \
 SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES DEFINES_MODULE=YES

xcodebuild archive \
 -scheme YOUR_PROJECT \
 -archivePath ./simulator/ \
 -sdk iphonesimulator \
 SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES DEFINES_MODULE=YES

xcodebuild -create-xcframework \
 -framework ./device.xcarchive/Products/Library/Frameworks/YOUR_PROJECT.framework \
 -framework ./simulator.xcarchive/Products/Library/Frameworks/YOUR_PROJECT.framework \
 -output ./YOUR_PROJECT.xcframework
  1. Notice how the Amplitude framework is not included in the Archive or XCFramework

Environment

  • SDK Version: 0.3.0
  • Device: All
  • OS Version: iOS ~

CGFloat property values are not sent to backend

Expected Behavior

CGFloat property values should be sent to the backend, or raise an error.

Current Behavior

The SDK silently fails to send these to the backend.

Possible Solution

Proposal PR

Steps to Reproduce

let properties = ["fontSize": CGFloat(12.0)]
amplitude.track(eventType: "userChangedFontSize", eventProperties: properties)

Environment

  • SDK Version: main / 0.7.2
  • OS Info: iPadOS 17.0.3

0.3.1 not sending any events

Expected Behavior

Events from app behaviour should display on amplitude platform.

Current Behavior

No events are showing after upgrading to AmplitudeSwift 0.3.1.

Possible Solution

Downgrade to AmplitudeSwift 0.3.0

Steps to Reproduce

  1. Bumped podfile dependency to 0.3.1.
  2. Built and ran new developer build of the app.
  3. Navigated through app to generate events (which worked previously on 0.3.0).
  4. No events are showing on Amplitude Platform, but they did show when using AmplitudeSwift 0.3.0.

Is is possible this is the cause? I did try specifying the SDK with the following but this didn't resolve it.

// 0.3.0 and 0.3.1
Configuration(apiKey: amplitudeDeveloperApiKey, logLevel: LogLevelEnum.DEBUG, serverZone: ServerZone.EU)

// 0.3.1 with tweak
Configuration(apiKey: amplitudeDeveloperApiKey, logLevel: LogLevelEnum.DEBUG, serverZone: ServerZone.EU, serverUrl: Constants.EU_DEFAULT_API_HOST)

Environment

  • SDK Version: 0.3.1
  • OS Info: iOS 16.2

'Invalid JSON request body' error occurs when user minimizes app.

Expected Behavior

Successful response (code 200)

Current Behavior

{
"code": 400,
"error": "Invalid JSON request body"
}
image

Steps to Reproduce

  1. Open iPhone settings
  2. Open app
  3. Change several permissions
  4. Run
  5. Minimze app (to trigger request)
  6. Check request (use any sniffer like charles)

Environment

  • iPhone 13 mini, iOS 17.0.3
  • AmplitudeSwift (1.0.0)

SDK repeatedly retries bad requests

Network requests fail with a 400 error code referring to the length of user_id or device_id. Both of these values appear to be set in the request data so I'm unsure why this fails. The client will then repeatedly retry this, in the sampled screenshot it's sent around 800 network requests.

Screenshot 2024-02-28 at 12 02 15

The client will also repeatedly call flush and fill up it's local event cache, in my case the size of this cache is around ~600mb, my colleague's is a few gb. This will peg CPU usage and gradually increase memory usage as well ad disk writes.

This is also occuring in production and reported by by performance monitoring we have in Sentry.

There's a few things going on here but the main issue I see is a bug in the retry logic of the client that I haven't been able to track down.

Migrating AMPTrackingOptions

I'm going to prepare slowly without changing it to Swift right away.

But I have a question.

스크린샷 2024-02-21 오전 10 57 47
I applied the option to 'AppDelegate' as above.

image

And it's in the Document.

What I'm curious about here is

  1. Do I need to create and manage a shared class for the generated 'amplitude'??
  2. Or is 'Amplitude' shared? (Anywhere you apply the option, does it apply everywhere??)
  3. How do I apply 'disableLatLng'? Documnet not found..
  4. I've never used 'defaultTracking' but should I just apply the option as shown in the document??

There are many parts that I don't understand even if I look at the document because it's still Newbie.

EventOptions

'EventOptions' initializer is inaccessible due to 'internal' protection level

What is the correct way to add options to the track method? if EventOptions is inaccessible?

setOnce operation does not work

Calling setOnce(property: String, value: Float) on Identify does not set the value properly

Expected Behavior

Value of property should be set only once

Current Behavior

A property name $set_once.PROPERTY_NAME is set

Possible Solution

Change SET_ONCE operation name in code

Steps to Reproduce

Call Identify.setOnce(...)

Environment

  • SDK Version: 1.3.0
  • OS Info: Any iOS

Tweak code generation

Summary

When we generate the code with ampli-cli we're getting some enum cases having reserved keywords names.
Now we need to escape them manually to be able to build.
There's a way to tweak the generation of the code to avoid it?

image

visionOS support

In my application (iOS/macOS/watchOS/visionOS), your SDK is working for visionOS but your web console did not support it (no device type, device OS, etc...), currently the only way to filter visionOS events is by the application version. Any plan to support it ?

Returning `nil` from a plugin crashes the app

When implementing a plugin with type enrichment and returning nil from execute(event:), the app crashes, because the event is force unwrapped here.

Allowing nil as a return value would make it possible to conditionally filter events using a plugin.

Expected Behavior

When a plugin returns a nil value after enrichment, the event should be ignored.

Current Behavior

The event is subsequently force unwrapped, which is nil, so the app crashes.

Possible Solution

Add a conditional unwrap of the event variable to the existing if let statement which wraps the call to the mediator:

internal func applyPlugin(pluginType: PluginType, event: BaseEvent?) -> BaseEvent? {
    var result: BaseEvent? = event
    if let mediator = plugins[pluginType], event {
        result = mediator.execute(event: event)
    }
    return result
}

Steps to Reproduce

  1. Implement and add this plugin:
class FilterPlugin: Plugin {
    var type: PluginType { .enrichment }

    func setup(amplitude: Amplitude) { }

    func execute(event: BaseEvent) -> BaseEvent? {
        guard event.eventType != "abc" else {
            return nil
        }
        return event
    }
}
  1. Track an event with the eventType that is checked against in the guard (in this example "abc").

Environment

  • SDK Version: v1.1.0
  • OS Info: Any

Broken Compilation using non-current SDKs

Expected Behavior

The package should be able to compile correctly when using the non-current SDK (current is iOS 17, I have to use iOS 16.4 at the moment)

Current Behavior

The package fails to compile due to the use of the #available macro added to the HttpClient in #136.

if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
    requestUrl = URL(string: url, encodingInvalidCharacters: false)
} else {
    requestUrl = URL(string: url)
}

The available macro can behave unexpectedly when using version numbers that are not yet known from older SDK's. This leads to a build failure:

[22:29:14]: ▸ ::error file=/Users/runner/Library/Developer/Xcode/DerivedData/Patient-bmxfeexsbebtsienjupwzgepdxcj/SourcePackages/checkouts/Amplitude-Swift/Sources/Amplitude/Utilities/HttpClient.swift,line=74,col=70::extra argument 'encodingInvalidCharacters' in call
[22:29:14]: ▸             requestUrl = URL(string: url, encodingInvalidCharacters: false)
[22:29:14]: ▸        

Possible Solution

Add an additional compiler check for a swift version to limit the available checking to a compatible version:

#if swift(>=5.9)
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
    requestUrl = URL(string: url, encodingInvalidCharacters: false)
} else {
    requestUrl = URL(string: url)
}
#else
// Fallback to the earlier behavior.
requestUrl = URL(string: url)
#endif

Steps to Reproduce

I would suggest you setup your GitHub actions to run using a matrix of multiple versions of macOS/Xcode/SDKs to help in catching potential issues like this.

Environment

  • SDK Version: Since 1.4.0
  • OS Info: macOS 14.3.1, Xcode 14.3.1, iOS 16.4

Carthage requires AnalyticsConnector on every DerivedData clean

Hi! I'm using AmplitudeSwift via Carthage (it's still better than SPM option in terms of caching). But when I clean DrivedData AmplitudeSwift missing AnalyticsConnector:

Expected Behavior

AmplitudeSwift has everything required for building via Carthage

Current Behavior

error: missing required module 'AnalyticsConnector'

Possible Solution

I think you need to update the root AmplitudeSwift project to use carthage version of AnalyticsConnector or maybe Pod version.
Because now it uses SPM version of AnalyticsConnector which I can find when I rebuild carthage in DerivedData.

Steps to Reproduce

  1. Add AmplitudeSwift to your Cartfile
  2. Bootstrap Carthage -> AmplitudeSwift is fetched and build, which produced AnalyticsConnector in DerivedData (not in the Carthage build dir
  3. Add AmplitudeSwift.xcframework to your project
  4. import AmplitudeSwift in any file
  5. Build the project -> build succeed
  6. Go to DerivedData and clean its content
  7. Try to build your project
  8. The error appears
  9. (rebuilding Carthage fixes this issues)

Environment

  • SDK Version: 1.4.0
  • OS Info: MacOS Ventura 13.5.2
  • Carthage Version: 0.39.1

Performance Checker Catches DispatchSemaphore Race

Expected Behavior

DispatchSemaphore seems like it isn't working as intended here
Relevant bug report in old SDK. But issue seems to persist here.

Current Behavior

It seems like there is a queue prioritization bug
Console output is:

Performance Checker: Thread running at QOS_CLASS_USER_INITIATED waiting on a lower QoS thread running at QOS_CLASS_UTILITY. Investigate ways to avoid priority inversions
image

Steps to Reproduce

Run in Xcode 15

Environment

  • SDK Version: v. 0.7.2
  • OS Version: MacOS 10.12.6 Monterey

Out of session events

Expected Behavior

Session ID is correctly (not -1) set in all events, including the first session for this user.

Current Behavior

Session ID is only correctly set in Start Session event for the first session of this user and all events in other sessions.

Reason

Amplitude_Swift SDK doesn't get the sessionId for events in the first session, check this method:

@discardableResult
public func track(eventType: String, eventProperties: [String: Any]? = nil, options: EventOptions? = nil)
    -> Amplitude

Possible solution

track method uses LAST_EVENT_TIME for sessionId on BaseEvent initialize

Workaround

Using sessionId, when sending an event

amplitude.track(
	event: .init(
		sessionId: sessionId,
		eventType: eventType,
		eventProperties: eventProperties
	)
)

Problems with this workaround:
There is no documentation, so I've just used tried to use all these methods and none of them really helped me
21 37 25 d9VhLlpB
but I stopped on using

let sessionId = Int64(Date().timeIntervalSince1970)
amplitude.refreshSessionTime(timestamp: sessionId)
UserDefaults.standard.set(sessionId, forKey: "sessionId")

When using this approach the sessionId in Start Session and other events don't match.
When trying to use other methods I get the same behavior or get End session in the first session of the user.

Steps to Reproduce

  1. Sample Amplitude configuration
let amplitude = Amplitude(configuration: Configuration(apiKey: amplitudeKey))
  1. Use a new simulator/device, that hasn't been registered by Amplitude
  2. Send any event
amplitude.track(eventType: eventType, eventProperties: eventProperties)
  1. Check this user in Amplitude, It would have Start Session with Session ID, but other events would be out-of-session (Session ID == -1)
    21 31 25 xVCB5YbJ

Environment

  • SDK Version: 0.3.0
  • OS Info: iPadOS 14-16.4

Persistent Storage uses caches/document directory

Expected Behavior

Application data should be stored in the application support directory reachable via FileManager.SearchPathDirectory.applicationSupportDirectory.

Current Behavior

Application data is being saved to either the user's document directory or the caches directory. The document's directory is less than ideal as it clutters up user space. The caches directory is also problematic as it can be purged by the system.

Possible Solution

Use the application support directory (FileManager.SearchPathDirectory.applicationSupportDirectory). On macOS, it's the ~/Library/Application Support directory. On iOS and other platforms it's app specific, but serves the same purpose.

Furthermore, you can mark a directory/file to be excluded from iCloud backup by setting attributes at the point of creation. More info here: Mark Nonpurgeable Data as Excludable

I've created a PR you can reference

Automatic screen name includes object address and makes it unusable

Expected Behavior

Current Behavior

Currently screen name is captured in a way that includes object address, which is different each time object instantiated. This way I can't filter by actual Screen Name because there are plenty of records for single screen name.
Screenshot 2023-11-23 at 16 36 12

Possible Solution

There are plenty of possible solutions, but the easiest one would be to just print Class of an object, and not include brackets, object address etc. So that it would be:
FriendProfile instead of <Evenly.FriendProfile: 0x10501e800>

Steps to Reproduce

  1. Just enable defaultTracking so that screenViews are tracked, so defaultTracking: .init(screenViews: true) or defaultTracking: .ALL and see what's received by Amplitude

Environment

  • SDK Version: Amplitude-Swift 1.1.0
  • OS Info: iOS 17.0.1, iOS Simulator iPhone 15 Pro Max

Absence of Int64 properties

Currently, we can't track properties with Int64 type without converting them to Int or String.

Environment

  • SDK Version: v.0.4.14

Automatic screen tracking doesn't work

Expected Behavior

Using defaultTracking.screenViews = true or DefaultTrackingOptions.ALL on Amplitude initialisation should enable automatic screen tracking

Current Behavior

Screen events don't track automatically.

Debugging shows that UIViewController.viewDidAppear swizzled successfully, but tracking fails on bundle check:

let bundle = Bundle(for: self.classForCoder)
if !bundle.bundlePath.hasPrefix(Bundle.main.bundlePath) {
return
}

where

(lldb) po bundle.bundlePath
"/System/Library/PrivateFrameworks/UIKitCore.framework"

(lldb) po Bundle.main.bundlePath
"/private/var/containers/Bundle/Application/4AC5FC00-2EE0-446D-AB8F-190B8B030758/myapp.app"

For context which might be related: my UIViewControllers are in a separate framework, not in the main bundle, but either way it must not interfere with tracking.

If I understand correctly, and as lldb printing above suggests - tracking can't happen because in my caseBundle.main.bundlePath obviously can't be a prefix for bundle.bundlePath.

Possible Solution

Revise bundle checks. I wonder what could have been the reason to put this check in the first place?

Steps to Reproduce

  1. Create a ViewController, potentially in a framework (referenced by main app target).
  2. Check if screen events are being tracked.

Environment

  • SDK Version: Amplitude-Swift 1.1.0
  • iOS version: 15.7.3
  • Xcode: 15.1
  • OS Info: MacOS 14.3.1 (23D60)

How to disableLatLng

image

The option that was present in Amplitude-iOS is not visible in Amplitude-Swift.

Disable IP Address tracking not working

We have initialized the Amplitude Swift SDK using the tracking options, as described in the documentation, to disable some data tracking, including the user IP address.

However, even using the latest 0.4.4 SDK, the IP address is still collected and visible in the Amplitude dashboard.

Is there a way to completely and successfully disable it?

Add the build number to the user version property value

Summary

Currently it looks like the version property value is set to CFBundleShortVersionString from the info.plist file. This displays a version like 1.1 in amplitude's User Look-Up view. The complete version string should include the build number as well which is the CFBundleVersion value from the info.plist file. Incorporating the build number, the full version property would ideally look like this 1.1 (16)

Motivations

If the build number isn't incorporated in the version property value, it's not possible to tell exactly what version of the app a customer is using since the CFBundleShortVersionString is not incremented for every binary published.

Platform property contains device family

Expected Behavior

platform user property used to be iOS (on Android it is set to Android)

Current Behavior

platform user property includes the device family i.e. iPhone10,3

Steps to Reproduce

        override var platform: String {
            var name: [Int32] = [CTL_HW, HW_MACHINE]
            var size: Int = 2
            sysctl(&name, 2, nil, &size, nil, 0)
            var hw_machine = [CChar](repeating: 0, count: Int(size))
            sysctl(&name, 2, &hw_machine, &size, nil, 0)
            let platform = String(cString: hw_machine)

            return platform // expected: iOS, actual: iPhone10,3
        }

Environment

  • SDK Version: 0.3.0
  • OS Info: iOS 15
  • Equivalent Android SDK: 1.8.1

`flushEventsOnClose` configuration option fails to deliver events

Expected Behavior

When the flushEventsOnClose configuration option is selected, any yet to be sent events will be flushed and delivered in a timely manner.

Current Behavior

Whilst a call to flush is made, the network request will be immediately cancelled by the system as the app loses focus. Events won't be delivered until the user next opens the app at the earliest. If this is the last time a user opens an app, these critical events for diagnosing user attrition will fail to be delivered at all.

Possible Solution

When an iOS app is backgrounded, any network requests which aren't specifically marked as background tasks will fail to complete. With the current implementation, this means that up to 30 seconds of events will be delayed until the next time the app is opened, or lost completely.

iOS does include an affordance to extend the time after an app loses foreground focus in which it can perform additional tasks, but these tasks need to be marked explicitly with calls to UIApplication.beginBackgroundTask and UIApplication.endBackgroundTask.

Unfortunately, this can't be achieved with an event callback alone as a background task should ideally be limited to around 5s, with a maximum deadline of 30s. This deadline is frequently exceeded with an event callback as the duration between when an event is tracked and when it is finally flushed through the queue frequently exceeds 30s and results in warnings from the system.

I've opened PR #68 as an example resolution, but would be happy with any solution or mechanism that ensures events can be successfully delivered.

Environment

  • SDK Version: v0.4.11
  • OS Info: iOS 16/17

Method Swizzling Causes Conflict with New Relic

Expected Behavior

Tracking should begin seamlessly at app launch.

Current Behavior

When launching with screenViews set to true, the call to amp_viewDidAppear triggers an exception in New Relic profiler.

Possible Solution

Potentially use an alternative to swizzling that doesn't trigger other SDKs? (Not sure if this is possible)

Steps to Reproduce

  1. Install Amplitude-Swift 0.6.0 alongside New Relic 7.4.6
  2. When initializing Amplitude-Swift, pass true for tracking screenViews (e.g. DefaultTrackingOptions(screenViews: true))
  3. Attempt to start your application.
  4. Observe the error thrown

Thread 1: "New Relic detected an unrecognized selector, 'amp_viewDidAppear:', sent to 'UIViewController'. It's possible _cmd was renamed by an unsafe method_exchangeImplementations()."

*** Terminating app due to uncaught exception 'NRInvalidArgumentException', reason: 'New Relic detected an unrecognized selector, 'amp_viewDidAppear:', sent to 'UIViewController'. It's possible _cmd was renamed by an unsafe method_exchangeImplementations().'
*** First throw call stack:
(
	0   CoreFoundation                      0x00000001803f3d70 __exceptionPreprocess + 236
	1   libobjc.A.dylib                     0x000000018019814c objc_exception_throw + 56
	2   NewRelic                            0x0000000114f05d68 NRMA__beginMethod + 744
	3   NewRelic                            0x0000000114f0632c NRMA__boolParamHandler + 56
	4   Argon                               0x00000001043f5e78 $sSo16UIViewControllerC14AmplitudeSwiftE17amp_viewDidAppearyySbF + 72
	5   Argon                               0x00000001043f6980 $sSo16UIViewControllerC14AmplitudeSwiftE17amp_viewDidAppearyySbFTo + 40
	6   UIKitCore                           0x000000018463e258 -[UIViewController _setViewAppearState:isAnimating:] + 832
	7   UIKitCore                           0x000000018463ec88 -[UIViewController __viewDidAppear:] + 168
	8   UIKitCore                           0x000000018463ef88 -[UIViewController _endAppearanceTransition:] + 248
	9   UIKitCore                           0x0000000184518f90 __48-[UIPresentationController transitionDidFinish:]_block_invoke + 140
	10  UIKitCore                           0x0000000185294438 -[_UIAfterCACommitBlock run] + 64
	11  UIKitCore                           0x000000018529490c -[_UIAfterCACommitQueue flush] + 188
	12  UIKitCore                           0x0000000184d97a0c _runAfterCACommitDeferredBlocks + 640
	13  UIKitCore                           0x0000000184d87430 _cleanUpAfterCAFlushAndRunDeferredBlocks + 128
	14  UIKitCore                           0x0000000184dba204 _afterCACommitHandler + 76
	15  CoreFoundation                      0x0000000180360f10 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
	16  CoreFoundation                      0x000000018035b5a4 __CFRunLoopDoObservers + 572
	17  CoreFoundation                      0x000000018035baf8 __CFRunLoopRun + 968
	18  CoreFoundation                      0x000000018035b218 CFRunLoopRunSpecific + 572
	19  GraphicsServices                    0x000000018c25f60c GSEventRunModal + 160
	20  UIKitCore                           0x0000000184d88a98 -[UIApplication _run] + 992
	21  UIKitCore                           0x0000000184d8d634 UIApplicationMain + 112
	22  Argon                               0x0000000102990998 main + 64
	23  dyld                                0x000000011475dcd8 start_sim + 20
	24  ???                                 0x00000001148e9f28 0x0 + 4639858472
	25  ???                                 0xaf5b000000000000 0x0 + 12635693179518058496
)
libc++abi: terminating with uncaught exception of type NSException

Environment

  • SDK Version: 0.6.0
  • OS Info: iOS 15.x, iOS 16.x

Flushing events on the main queue causing an app hang

We were experiencing the HTTP 400 bug due to having a user id whose length < 5 which was causing OOMs consistently.
Changing the minIdLength property to 1 seemed to fix that issue.

However the subsequent issue is, from what I can see, flushing the local events that were previously failing to send.
the issue seems to be due to flushing happening on the main thread and causing a hang during getEventsAsString from PersistentStorage

Here's a stack trace from one of the hangs:
App Hang: The app was terminated while unresponsive

0 CoreFoundation +0x6b88 CF_IS_OBJC
1 +0x703e8001adcf5a5c 0x703e8001adcf5a5c
2 CoreFoundation +0x4b90 CFStringCompareWithOptionsAndLocale
3 Foundation +0x255ddc specialized UnsafeMutableBufferPointer.stableSortImpl(by:)
4 Foundation +0x255ad4 specialized MutableCollection<>.sort(by:)
5 Foundation +0x43d70 JSONWriter.serializeObject(
:depth:)
6 Foundation +0x454d4 JSONWriter.serializeArray(
:depth:)
7 Foundation +0x43b44 JSONWriter.serializeJSON(
:depth:)
8 Foundation +0x43170 JSONEncoder.encode(:value:)
9 Foundation +0x42f08 JSONEncoder.encode(:)
10 Foundation +0x42ec0 dispatch thunk of JSONEncoder.encode
(:)
11 relevant: PersistentStorage.eventsToJSONString(events:)
12 relevant: PersistentStorage.readV2File(content:)
13 relevant: PersistentStorage.getEventsString(eventBlock:)
14 relevant: protocol witness for Storage.getEventsString(eventBlock:) in conformance PersistentStorage
15 relevant: closure #1 in EventPipeline.flush(completion:)
16 relevant: thunk for @callee_guaranteed () -> ()
17 relevant: thunk for @escaping @callee_guaranteed () -> ()
18 libdispatch.dylib +0x42fc __dispatch_client_callout
19 libdispatch.dylib +0x136b0 __dispatch_lane_barrier_sync_invoke_and_complete
20 relevant: EventPipeline.flush(completion:)
21 relevant: closure #1 in EventPipeline.init(amplitude:)
22 relevant: closure #1 in QueueTimer.init(interval:once:queue:handler:)
23 relevant: thunk for @escaping @callee_guaranteed () -> ()

Possible Solution

The QueueTimer's initializer takes in a queue that's used to create the DispatchSourceTimer, it's currently defaulting to main. Moving it off the main queue might make sense, didn't really dive more into the code.

Steps to Reproduce

I think this is what's happening

  • no min id length -> events failing to send and being saved locally
  • events stacking up locally
  • min id length set -> events now sending -> app hang due to above

Environment

  • SDK Version: 1.4.3

Events sent with “unknown” source

Expected Behavior

Events should be reported in Amplitude as "ios" since I have set up a Source named "ios" in both my development and production environments.

Current Behavior

Events are reported as "unknown" when using the Amplitude-Swift SDK.

Possible Solution

I think this might be happening because there’s no way to specify a Plan when initializing the Configuration. The reason for this is that Plan has no accessible public initializers.

Steps to Reproduce

  1. Create a Source in Amplitude’s web UI.
  2. Setup the SDK with the API token for that source.
  3. Track an event.

Environment

  • SDK Version: 0.3.1
  • OS Info: iOS 16

Is there a way to clear persisted events?

Summary

Following a @StateObject update infinite loop that lead my SwiftUI View to update what seems to be several thousand times per second, and even though the issue had been resolved, I would regularly randomly end up with significant sustained (> 5 minutes) spikes in memory (> 1.5GB) and CPU (~190%) usage.

Investigating memory allocations & the memory graph lead me to PersistentStorageResponseHandler and HTTPClient. I imagine my little mistake must have generated a huge amount of locally persisted unsent events.

Because of that, every time I would launch the app, the Amplitude SDK would, at some point, start trying to upload these events.

I could confirm the origin by disabling the Amplitude SDK, and deleting and re-running the app before re-enabling the SDK solved my issue. But that wouldn't be a solution for end-users.

Is there a way to determine the volume of persisted events and to clean them up if necessary?

Server Side Swift Support

Summary

Although the repository specially called out Apple platforms (This is Amplitude's latest version of the iOS SDK, covering iOS/tvOS/macOS/watchOS.), Swift as a language is growing beyond those specific usages. With a few modifications, this library can be adapted to run on other Swift native environments (like Linux and Windows).

Motivations

I had a PR that started this work, but recent changes has made it difficult to stay on top keeping it merge-ready. When library developers aren't trained to think about multiple platform support, it's easy to make decisions that directly make that support hard to achieve.

Here are some of the areas identified that would need to be addressed to make this library compatible with non-apple platforms:

Isolate OSLog usage by checking for #if canImport(os.log)

  • Preferably use a cross-platform solution like swift-log

Add conditional imports for FoundationNetworking where required. (#if canImport(FoundationNetworking))

  • On non-apple platforms, networking classes like URL, URLRequest, URLSession are part of the FoundationNetworking package.

Setup a CSQLite map for linux systems

      .systemLibrary(
           name: "CSQLite",
           pkgConfig: "sqlite3",
           providers: [
               .apt(["sqlite3", "libsqlite3-dev"])
           ]
       ),
       .target(
           name: "AmplitudeSwift",
           dependencies: [
               .target(name: "CSQLite", condition: .when(platforms: [.linux]))
           ],
           path: "Sources/Amplitude",
           exclude: ["../../Examples/", "../../Tests/"]
       ),

Beware of DispatchQueue.main

This may not exist or function differently on other platforms. In a server-side environment, using this queue often does nothing.

Crashes in SDK

Hi there. I've discovered two different crashes in our reports. I can't tell how they were triggered though since the crashes were collected anonymously.

Incident Identifier: FC7B2B95-350A-4848-8ACE-3DB7FAA788D9
Hardware Model:      iPhone15,3
AppStoreTools:       14C17
AppVariant:          1:iPhone15,3:16
Beta:                YES
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]

Date/Time:           2023-03-03 20:43:14.9185 -0500
Launch Time:         2023-03-03 17:23:27.6421 -0500
OS Version:          iPhone OS 16.4 (20E5223e)
Release Type:        Beta
Baseband Version:    1.66.01
Report Version:      104

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000001b4ba369c
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Terminating Process: exc handler [601]

Triggered by Thread:  0


Thread 0 name:
Thread 0 Crashed:
0   Foundation                    	0x00000001b4ba369c __DataStorage.init(bytes:length:) + 240 (<compiler-generated>:0)
1   Foundation                    	0x00000001b4baf878 closure #2 in Data.init<A>(_:) + 88 (Data.swift:0)
2   libswiftCore.dylib            	0x00000001b447b494 String.UTF8View.withContiguousStorageIfAvailable<A>(_:) + 108 (StringGuts.swift:0)
3   libswiftCore.dylib            	0x00000001b447b034 protocol witness for Sequence.withContiguousStorageIfAvailable<A>(_:) in conformance String.UTF8View + 24 (<compiler-generated>:0)
4   libswiftCore.dylib            	0x00000001b45eb458 dispatch thunk of Sequence.withContiguousStorageIfAvailable<A>(_:) + 32 (:-1)
5   Foundation                    	0x00000001b4bb9d2c specialized Data.init<A>(_:) + 668 (Data.swift:2099)
6   Foundation                    	0x00000001b4b7909c StringProtocol.data(using:allowLossyConversion:) + 252 (<compiler-generated>:0)
7   XXX                          	0x00000001015630e8 HttpClient.getRequestData(events:) + 480 (HttpClient.swift:79)
8   XXX                          	0x00000001015610cc HttpClient.upload(events:completion:) + 24 (HttpClient.swift:25)
9   XXX                          	0x00000001015610cc EventPipeline.flush(completion:) + 1996 (EventPipeline.swift:65)
10  XXX                          	0x0000000101561c60 closure #1 in EventPipeline.init(amplitude:) + 52 (EventPipeline.swift:31)
11  XXX                          	0x0000000101561c60 partial apply for closure #1 in EventPipeline.init(amplitude:) + 68 (<compiler-generated>:0)
12  XXX                          	0x0000000101568508 closure #1 in QueueTimer.init(interval:queue:handler:) + 64 (QueueTimer.swift:38)
13  XXX                          	0x0000000101568508 partial apply for closure #1 in QueueTimer.init(interval:queue:handler:) + 84 (<compiler-generated>:0)
14  XXX                          	0x00000001015679c8 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
15  libdispatch.dylib             	0x00000001c19e0f48 _dispatch_client_callout + 20 (object.m:560)
16  libdispatch.dylib             	0x00000001c19e43cc _dispatch_continuation_pop + 504 (inline_internal.h:2633)
17  libdispatch.dylib             	0x00000001c19f7908 _dispatch_source_invoke + 1588 (source.c:596)
18  libdispatch.dylib             	0x00000001c19ef620 _dispatch_main_queue_drain + 756 (inline_internal.h:0)
19  libdispatch.dylib             	0x00000001c19ef31c _dispatch_main_queue_callback_4CF + 44 (queue.c:7916)
20  CoreFoundation                	0x00000001ba5a9d18 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1780)
21  CoreFoundation                	0x00000001ba58b650 __CFRunLoopRun + 1992 (CFRunLoop.c:3147)
22  CoreFoundation                	0x00000001ba5904dc CFRunLoopRunSpecific + 612 (CFRunLoop.c:3418)
23  GraphicsServices              	0x00000001f606a35c GSEventRunModal + 164 (GSEvent.c:2196)
24  UIKitCore                     	0x00000001bc925864 -[UIApplication _run] + 888 (UIApplication.m:3773)
25  UIKitCore                     	0x00000001bc9254c8 UIApplicationMain + 340 (UIApplication.m:5363)
26  libswiftUIKit.dylib           	0x00000001c2f9e0b0 UIApplicationMain(_:_:_:_:) + 104 (UIKit.swift:538)
27  XXX                          	0x0000000100e09088 specialized static UIApplicationDelegate.main() + 80 (<compiler-generated>:15)
28  XXX                          	0x0000000100e09088 static AppDelegate.$main() + 88 (AppDelegate.swift:0)
29  XXX                          	0x0000000100e09088 main + 104
30  dyld                          	0x00000001da2dbdec start + 2220 (dyldMain.cpp:1165)

...

Thread 3 name:
Thread 3:
0   libswiftCore.dylib            	0x00000001b46c1270 swift_slowAlloc.cold.1 + 16 (Heap.cpp:81)
1   libswiftCore.dylib            	0x00000001b4615e8c swift_slowAlloc + 120 (Debug.h:50)
2   libswiftCore.dylib            	0x00000001b4616050 swift_allocObject + 64 (HeapObject.cpp:139)
3   libswiftCore.dylib            	0x00000001b4470e84 _allocateStringStorage(codeUnitCapacity:) + 180 (StringStorage.swift:235)
4   libswiftCore.dylib            	0x00000001b45a8818 specialized static __StringStorage.create(initializingFrom:codeUnitCapacity:isASCII:) + 52 (StringStorage.swift:310)
5   libswiftCore.dylib            	0x00000001b44625d4 _StringGuts.prepareForAppendInPlace(totalCount:otherUTF8Count:) + 240 (<compiler-generated>:0)
6   libswiftCore.dylib            	0x00000001b446277c _StringGuts.append(_:) + 220 (StringGutsRangeReplaceable.swift:230)
7   XXX                          	0x0000000101562ffc DefaultStringInterpolation.write(_:) + 16 (<compiler-generated>:0)
8   XXX                          	0x0000000101562ffc protocol witness for TextOutputStream.write(_:) in conformance DefaultStringInterpolation + 16 (<compiler-generated>:0)
9   XXX                          	0x0000000101562ffc specialized String.write<A>(to:) + 16 (<compiler-generated>:0)
10  XXX                          	0x0000000101562ffc specialized protocol witness for TextOutputStreamable.write<A>(to:) in conformance String + 16 (<compiler-generated>:0)
11  XXX                          	0x0000000101562ffc specialized DefaultStringInterpolation.appendInterpolation<A>(_:) + 16 (HttpClient.swift:0)
12  XXX                          	0x0000000101562ffc HttpClient.getRequestData(events:) + 244
13  XXX                          	0x00000001015610cc HttpClient.upload(events:completion:) + 24 (HttpClient.swift:25)
14  XXX                          	0x00000001015610cc EventPipeline.flush(completion:) + 1996 (EventPipeline.swift:65)
15  XXX                          	0x000000010156089c EventPipeline.put(event:completion:) + 696 (EventPipeline.swift:42)
16  XXX                          	0x0000000101565508 closure #1 in PersistentStorageResponseHandler.handleBadRequestResponse(data:) + 12 (PersistentStorageResponseHandler.swift:88)
17  XXX                          	0x0000000101565508 specialized Sequence.forEach(_:) + 12 (<compiler-generated>:0)
18  XXX                          	0x0000000101565508 PersistentStorageResponseHandler.handleBadRequestResponse(data:) + 3236 (PersistentStorageResponseHandler.swift:87)
19  XXX                          	0x0000000101565bb0 PersistentStorageResponseHandler.handle(result:) + 424 (PersistentStorageResponseHandler.swift:139)
20  XXX                          	0x0000000101565d60 protocol witness for ResponseHandler.handle(result:) in conformance PersistentStorageResponseHandler + 24 (<compiler-generated>:0)
21  XXX                          	0x00000001015616ec closure #1 in EventPipeline.flush(completion:) + 292 (EventPipeline.swift:72)
22  XXX                          	0x0000000101562bb8 closure #1 in HttpClient.upload(events:completion:) + 292 (HttpClient.swift:35)
23  XXX                          	0x0000000101562308 thunk for @escaping @callee_guaranteed @Sendable (@guaranteed Data?, @guaranteed NSURLResponse?, @guaranteed Error?) -> () + 148 (<compiler-generated>:0)
24  CFNetwork                     	0x00000001bb54593c __40-[__NSURLSessionLocal taskForClassInfo:]_block_invoke + 484 (LocalSession.mm:718)
25  CFNetwork                     	0x00000001bb555624 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke_2 + 164 (LocalSessionTask.mm:544)
26  libdispatch.dylib             	0x00000001c19df3bc _dispatch_call_block_and_release + 32 (init.c:1518)
27  libdispatch.dylib             	0x00000001c19e0f48 _dispatch_client_callout + 20 (object.m:560)
28  libdispatch.dylib             	0x00000001c19e85d0 _dispatch_lane_serial_drain + 668 (inline_internal.h:2633)
29  libdispatch.dylib             	0x00000001c19e913c _dispatch_lane_invoke + 436 (queue.c:3940)
30  libdispatch.dylib             	0x00000001c19f3cdc _dispatch_workloop_worker_thread + 648 (queue.c:6875)
31  libsystem_pthread.dylib       	0x000000021a58dddc _pthread_wqthread + 288 (pthread.c:2618)
32  libsystem_pthread.dylib       	0x000000021a58db7c start_wqthread + 8 (:-1)

...

Thread 0 crashed with ARM Thread State (64-bit):
    x0: 0x0000000000000000   x1: 0x000000016eff9ed8   x2: 0x0000000000008000   x3: 0x0000000000000000
    x4: 0x0000000003000001   x5: 0x0000000000000003   x6: 0x0000000000000000   x7: 0x0000000000000000
    x8: 0x0000000210d1ff6c   x9: 0x000000000000000c  x10: 0xffffffffffffc000  x11: 0x0000000000000000
   x12: 0x0000000000000050  x13: 0x00000000001ff800  x14: 0x00000000000007fb  x15: 0x00000000ed81d891
   x16: 0xfffffffffffffff1  x17: 0x0000000212186850  x18: 0x0000000000000000  x19: 0x0000000000005748
   x20: 0x0000000286276d00  x21: 0x00000003d7ff4020  x22: 0x0000000286276d10  x23: 0x0000000000005748
   x24: 0x00000003d7ff4020  x25: 0x00000002121199e8  x26: 0x00000001600f4728  x27: 0x00000001600f48a0
   x28: 0x000000016effa130   fp: 0x000000016effa040   lr: 0x9b510001b4ba3614
    sp: 0x000000016effa020   pc: 0x00000001b4ba369c cpsr: 0x40001000
   esr: 0xf2000001 (Breakpoint) brk 1

Incident Identifier: 6B8E313C-6947-4A62-9283-10D5E7268EAE
Hardware Model:      iPhone11,8
AppStoreTools:       14C17
AppVariant:          1:iPhone11,8:14
Beta:                YES
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]


Date/Time:           2023-03-03 16:51:20.1381 +0800
Launch Time:         2023-03-03 16:47:46.8714 +0800
OS Version:          iPhone OS 14.7.1 (18G82)
Release Type:        User
Baseband Version:    3.04.01
Report Version:      104

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x000000000000000c
VM Region Info: 0xc is not in any region.  Bytes before following region: 4372348916
      REGION TYPE                 START - END      [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      UNUSED SPACE AT START
--->  
      __TEXT                   1049cc000-1049d0000 [   16K] r-x/r-x SM=COW  ...XXX.app/XXX

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [4023]
Triggered by Thread:  0

Thread 0 name:
Thread 0 Crashed:
0   libobjc.A.dylib               	0x00000001a132cd40 AutoreleasePoolPage::AutoreleasePoolPage(AutoreleasePoolPage*) + 88 (NSObject-internal.h:96)
1   libobjc.A.dylib               	0x00000001a132cb18 AutoreleasePoolPage::autoreleaseFullPage(objc_object*, AutoreleasePoolPage*) + 64 (NSObject.mm:759)
2   libobjc.A.dylib               	0x00000001a132c99c objc_object::rootAutorelease2() + 112 (NSObject.mm:1071)
3   Foundation                    	0x000000018daa9b70 -[NSString(NSPathUtilities) lastPathComponent] + 300 (NSPathUtilities.m:1101)
4   libswiftFoundation.dylib      	0x00000001902d13c0 URL.lastPathComponent.getter + 28
5   XXX                          	0x0000000105120258 closure #2 in PersistentStorage.getEventFiles(includeUnfinished:) + 20 (PersistentStorage.swift:219)
6   XXX                          	0x0000000105120258 specialized _merge<A>(low:mid:high:buffer:by:) + 1004 (<compiler-generated>:0)
7   XXX                          	0x000000010511fbb0 specialized UnsafeMutableBufferPointer._mergeTopRuns(_:buffer:by:) + 444 (<compiler-generated>:0)
8   XXX                          	0x000000010511f654 specialized closure #1 in UnsafeMutableBufferPointer._stableSortImpl(by:) + 1812
9   XXX                          	0x000000010511eeb8 specialized UnsafeMutableBufferPointer._stableSortImpl(by:) + 224 (<compiler-generated>:0)
10  XXX                          	0x000000010511ed78 specialized MutableCollection<>.sort(by:) + 108 (<compiler-generated>:0)
11  XXX                          	0x000000010511bfa8 PersistentStorage.getEventFiles(includeUnfinished:) + 1224
12  XXX                          	0x000000010511b870 closure #1 in PersistentStorage.read<A>(key:) + 196 (PersistentStorage.swift:57)
13  XXX                          	0x0000000105121944 partial apply for closure #1 in PersistentStorage.read<A>(key:) + 24 (<compiler-generated>:0)
14  libswiftDispatch.dylib        	0x00000001a1e37e04 partial apply for thunk for @callee_guaranteed () -> (@out A, @error @owned Error) + 28 (<compiler-generated>:0)
15  libswiftDispatch.dylib        	0x00000001a1e37f48 thunk for @callee_guaranteed () -> (@out A, @error @owned Error)partial apply + 16
16  libswiftDispatch.dylib        	0x00000001a1e36278 closure #1 in closure #1 in OS_dispatch_queue._syncHelper<A>(fn:execute:rescue:) + 168 (Queue.swift:319)
17  libswiftDispatch.dylib        	0x00000001a1e37d08 partial apply for thunk for @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
18  libswiftDispatch.dylib        	0x00000001a1e35f30 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
19  libdispatch.dylib             	0x000000018c41381c _dispatch_client_callout + 20 (object.m:559)
20  libdispatch.dylib             	0x000000018c422d5c _dispatch_sync_invoke_and_complete_recurse + 68 (queue.c:998)
21  libdispatch.dylib             	0x000000018c4227b4 _dispatch_sync_f_slow + 176 (queue.c:1749)
22  libswiftDispatch.dylib        	0x00000001a1e36d18 implicit closure #2 in implicit closure #1 in OS_dispatch_queue.sync<A>(execute:) + 180
23  libswiftDispatch.dylib        	0x00000001a1e374ac partial apply for implicit closure #2 in implicit closure #1 in OS_dispatch_queue.sync<A>(execute:) + 56 (<compiler-generated>:0)
24  libswiftDispatch.dylib        	0x00000001a1e360b0 OS_dispatch_queue._syncHelper<A>(fn:execute:rescue:) + 372 (Queue.swift:317)
25  libswiftDispatch.dylib        	0x00000001a1e368a0 OS_dispatch_queue.sync<A>(execute:) + 168 (Queue.swift:369)
26  XXX                          	0x000000010511b798 PersistentStorage.read<A>(key:) + 80 (PersistentStorage.swift:53)
27  XXX                          	0x000000010511e2b0 protocol witness for Storage.read<A>(key:) in conformance PersistentStorage + 20 (<compiler-generated>:0)
28  XXX                          	0x0000000105128c40 EventPipeline.flush(completion:) + 832 (EventPipeline.swift:55)
29  XXX                          	0x00000001051161e4 AmplitudeDestinationPlugin.flush() + 40 (AmplitudeDestinationPlugin.swift:42)
30  XXX                          	0x0000000105122a80 closure #1 in Amplitude.flush() + 12 (Amplitude.swift:226)
31  XXX                          	0x0000000105122a80 closure #1 in Timeline.apply(_:) + 12 (Timeline.swift:129)
32  XXX                          	0x0000000105122a80 specialized Sequence.forEach(_:) + 12 (<compiler-generated>:0)
33  XXX                          	0x0000000105122a80 specialized Timeline.apply(_:) + 344 (Timeline.swift:128)
34  XXX                          	0x000000010511a708 Amplitude.flush() + 12 (Amplitude.swift:224)
35  XXX                          	0x000000010511a708 Amplitude.onExitForeground() + 12 (Amplitude.swift:287)
36  XXX                          	0x000000010511a708 specialized AmplitudeDestinationPlugin.applicationDidEnterBackground(application:) + 92 (IOSLifecycleMonitor.swift:102)
37  XXX                          	0x000000010511a67c AmplitudeDestinationPlugin.applicationDidEnterBackground(application:) + 4 (<compiler-generated>:0)
38  XXX                          	0x000000010511a67c protocol witness for IOSLifecycle.applicationDidEnterBackground(application:) in conformance AmplitudeDestinationPlugin + 20
39  XXX                          	0x0000000105123048 closure #1 in IOSLifecycleMonitor.didEnterBackground(notification:) + 112 (IOSLifecycleMonitor.swift:88)
40  XXX                          	0x0000000105123048 closure #1 in Timeline.apply(_:) + 112 (Timeline.swift:129)
41  XXX                          	0x0000000105123048 specialized Sequence.forEach(_:) + 112 (<compiler-generated>:0)
42  XXX                          	0x0000000105123048 specialized Timeline.apply(_:) + 448 (Timeline.swift:128)
43  XXX                          	0x000000010511a3ec specialized Timeline.apply(_:) + 8 (<compiler-generated>:0)
44  XXX                          	0x000000010511a3ec IOSLifecycleMonitor.didEnterBackground(notification:) + 16 (IOSLifecycleMonitor.swift:262)
45  XXX                          	0x000000010511a3ec IOSLifecycleMonitor.notificationResponse(notification:) + 340 (IOSLifecycleMonitor.swift:54)
46  XXX                          	0x000000010511a4a4 @objc IOSLifecycleMonitor.notificationResponse(notification:) + 48 (<compiler-generated>:0)
47  CoreFoundation                	0x000000018c781684 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 28 (CFNotificationCenter.c:706)
48  CoreFoundation                	0x000000018c78162c ___CFXRegistrationPost_block_invoke + 52 (CFNotificationCenter.c:173)
49  CoreFoundation                	0x000000018c780b98 _CFXRegistrationPost + 440 (CFNotificationCenter.c:198)
50  CoreFoundation                	0x000000018c780558 _CFXNotificationPost + 716 (CFNotificationCenter.c:1071)
51  Foundation                    	0x000000018da8745c -[NSNotificationCenter postNotificationName:object:userInfo:] + 64 (NSNotification.m:575)
52  UIKitCore                     	0x000000018f223610 __47-[UIApplication _applicationDidEnterBackground]_block_invoke + 316 (UIApplication.m:6588)
53  UIKitCore                     	0x000000018eafc9e4 +[UIViewController _performWithoutDeferringTransitionsAllowingAnimation:actions:] + 164 (UIViewController.m:7039)
54  UIKitCore                     	0x000000018f2233a8 -[UIApplication _applicationDidEnterBackground] + 144 (UIApplication.m:6576)
55  UIKitCore                     	0x000000018e870164 __101-[_UISceneLifecycleMultiplexer _evalTransitionToSettings:fromSettings:forceExit:withTransitionStore:]_block_invoke_2 + 908 (_UISceneLifecycleMultiplexer.m:719)
56  UIKitCore                     	0x000000018edd8458 _UIScenePerformActionsWithLifecycleActionMask + 104 (_UISceneLifecycleState.m:109)
57  UIKitCore                     	0x000000018e86fd3c __101-[_UISceneLifecycleMultiplexer _evalTransitionToSettings:fromSettings:forceExit:withTransitionStore:]_block_invoke + 224 (_UISceneLifecycleMultiplexer.m:549)
58  UIKitCore                     	0x000000018e86f744 -[_UISceneLifecycleMultiplexer _performBlock:withApplicationOfDeactivationReasons:fromReasons:] + 300 (_UISceneLifecycleMultiplexer.m:498)
59  UIKitCore                     	0x000000018e86fb4c -[_UISceneLifecycleMultiplexer _evalTransitionToSettings:fromSettings:forceExit:withTransitionStore:] + 768 (_UISceneLifecycleMultiplexer.m:548)
60  UIKitCore                     	0x000000018e86f388 -[_UISceneLifecycleMultiplexer uiScene:transitionedFromState:withTransitionContext:] + 340 (_UISceneLifecycleMultiplexer.m:454)
61  UIKitCore                     	0x000000018e69b0c4 -[UIScene _invalidate] + 804 (UIScene.m:689)
62  UIKitCore                     	0x000000018f4963b4 -[UIWindowScene _invalidate] + 52 (UIWindowScene.m:268)
63  UIKitCore                     	0x000000018f2199f4 -[UIApplication workspace:willDestroyScene:withTransitionContext:completion:] + 208 (UIApplication.m:3741)
64  UIKitCore                     	0x000000018ed0f708 -[UIApplicationSceneClientAgent scene:willInvalidateWithEvent:completion:] + 388 (UIApplicationSceneClientAgent.m:61)
65  FrontBoardServices            	0x000000019bdf8794 -[FBSScene _callOutQueue_agent_willDestroyWithTransitionContext:completion:] + 284 (FBSScene.m:452)
66  FrontBoardServices            	0x000000019be25b04 __84-[FBSWorkspaceScenesClient _queue_invalidateScene:withTransitionContext:completion:]_block_invoke_2 + 128 (FBSWorkspaceScenesClient.m:574)
67  FrontBoardServices            	0x000000019be076a4 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 240 (FBSWorkspace.m:355)
68  FrontBoardServices            	0x000000019be25958 __84-[FBSWorkspaceScenesClient _queue_invalidateScene:withTransitionContext:completion:]_block_invoke + 332 (FBSWorkspaceScenesClient.m:573)
69  libdispatch.dylib             	0x000000018c41381c _dispatch_client_callout + 20 (object.m:559)
70  libdispatch.dylib             	0x000000018c41730c _dispatch_block_invoke_direct + 268 (queue.c:468)
71  FrontBoardServices            	0x000000019be4bfa0 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 48 (FBSSerialQueue.m:184)
72  FrontBoardServices            	0x000000019be4bc30 -[FBSSerialQueue _targetQueue_performNextIfPossible] + 448 (FBSSerialQueue.m:227)
73  FrontBoardServices            	0x000000019be4c184 -[FBSSerialQueue _performNextFromRunLoopSource] + 32 (FBSSerialQueue.m:258)
74  CoreFoundation                	0x000000018c7a0990 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (CFRunLoop.c:1967)
75  CoreFoundation                	0x000000018c7a088c __CFRunLoopDoSource0 + 208 (CFRunLoop.c:2011)
76  CoreFoundation                	0x000000018c79fb90 __CFRunLoopDoSources0 + 268 (CFRunLoop.c:2048)
77  CoreFoundation                	0x000000018c799b70 __CFRunLoopRun + 820 (CFRunLoop.c:2925)
78  CoreFoundation                	0x000000018c799308 CFRunLoopRunSpecific + 600 (CFRunLoop.c:3242)
79  GraphicsServices              	0x00000001a3e1c734 GSEventRunModal + 164 (GSEvent.c:2259)
80  UIKitCore                     	0x000000018f21775c -[UIApplication _run] + 1072 (UIApplication.m:3269)
81  UIKitCore                     	0x000000018f21cfcc UIApplicationMain + 168 (UIApplication.m:4740)
82  libswiftUIKit.dylib           	0x00000001a059e24c UIApplicationMain(_:_:_:_:) + 104 (UIKit.swift:528)
83  XXX                          	0x00000001049d1088 specialized static UIApplicationDelegate.main() + 80 (<compiler-generated>:15)
84  XXX                          	0x00000001049d1088 static AppDelegate.$main() + 88 (AppDelegate.swift:0)
85  XXX                          	0x00000001049d1088 main + 104
86  libdyld.dylib                 	0x000000018c455cf8 start + 4 (:-1)

...

Thread 6 name:
Thread 6:
0   libsystem_kernel.dylib        	0x00000001baa131a8 kevent_id + 8 (:-1)
1   libdispatch.dylib             	0x000000018c434fc8 _dispatch_kq_poll + 232 (event_kevent.c:750)
2   libdispatch.dylib             	0x000000018c435a84 _dispatch_event_loop_wait_for_ownership + 440 (event_kevent.c:2203)
3   libdispatch.dylib             	0x000000018c422bec __DISPATCH_WAIT_FOR_QUEUE__ + 348 (queue.c:1657)
4   libdispatch.dylib             	0x000000018c422798 _dispatch_sync_f_slow + 148 (queue.c:1738)
5   libswiftDispatch.dylib        	0x00000001a1e36d18 implicit closure #2 in implicit closure #1 in OS_dispatch_queue.sync<A>(execute:) + 180
6   libswiftDispatch.dylib        	0x00000001a1e374ac partial apply for implicit closure #2 in implicit closure #1 in OS_dispatch_queue.sync<A>(execute:) + 56 (<compiler-generated>:0)
7   libswiftDispatch.dylib        	0x00000001a1e360b0 OS_dispatch_queue._syncHelper<A>(fn:execute:rescue:) + 372 (Queue.swift:317)
8   libswiftDispatch.dylib        	0x00000001a1e368a0 OS_dispatch_queue.sync<A>(execute:) + 168 (Queue.swift:369)
9   XXX                          	0x000000010511e28c PersistentStorage.write(key:value:) + 40 (PersistentStorage.swift:32)
10  XXX                          	0x000000010511e28c protocol witness for Storage.write(key:value:) in conformance PersistentStorage + 60 (<compiler-generated>:31)
11  XXX                          	0x0000000105128684 EventPipeline.put(event:completion:) + 160 (EventPipeline.swift:39)
12  XXX                          	0x000000010512d508 closure #1 in PersistentStorageResponseHandler.handleBadRequestResponse(data:) + 12 (PersistentStorageResponseHandler.swift:88)
13  XXX                          	0x000000010512d508 specialized Sequence.forEach(_:) + 12 (<compiler-generated>:0)
14  XXX                          	0x000000010512d508 PersistentStorageResponseHandler.handleBadRequestResponse(data:) + 3236 (PersistentStorageResponseHandler.swift:87)
15  XXX                          	0x000000010512dbb0 PersistentStorageResponseHandler.handle(result:) + 424 (PersistentStorageResponseHandler.swift:139)
16  XXX                          	0x000000010512dd60 protocol witness for ResponseHandler.handle(result:) in conformance PersistentStorageResponseHandler + 24 (<compiler-generated>:0)
17  XXX                          	0x00000001051296ec closure #1 in EventPipeline.flush(completion:) + 292 (EventPipeline.swift:72)
18  XXX                          	0x000000010512abb8 closure #1 in HttpClient.upload(events:completion:) + 292 (HttpClient.swift:35)
19  XXX                          	0x000000010512a308 thunk for @escaping @callee_guaranteed @Sendable (@guaranteed Data?, @guaranteed NSURLResponse?, @guaranteed Error?) -> () + 148 (<compiler-generated>:0)
20  CFNetwork                     	0x000000018ce4b3dc __40-[__NSURLSessionLocal taskForClassInfo:]_block_invoke + 540 (LocalSession.mm:687)
21  CFNetwork                     	0x000000018ce5d768 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 244 (LocalSessionTask.mm:584)
22  libdispatch.dylib             	0x000000018c411a84 _dispatch_call_block_and_release + 32 (init.c:1466)
23  libdispatch.dylib             	0x000000018c41381c _dispatch_client_callout + 20 (object.m:559)
24  libdispatch.dylib             	0x000000018c41b004 _dispatch_lane_serial_drain + 620 (inline_internal.h:2557)
25  libdispatch.dylib             	0x000000018c41bc34 _dispatch_lane_invoke + 456 (queue.c:3862)
26  libdispatch.dylib             	0x000000018c4264bc _dispatch_workloop_worker_thread + 764 (queue.c:6589)
27  libsystem_pthread.dylib       	0x00000001d84967a4 _pthread_wqthread + 276 (pthread.c:2436)
28  libsystem_pthread.dylib       	0x00000001d849d74c start_wqthread + 8 (:-1)

...

Thread 0 crashed with ARM Thread State (64-bit):
    x0: 0x0000000000000000   x1: 0x00000001077fd000   x2: 0x0000000000000000   x3: 0x0000000000800000
    x4: 0x0000000000000000   x5: 0x0000000000000000   x6: 0x0000000000000001   x7: 0x0000000000000000
    x8: 0x0000000000000038   x9: 0x00000001066878c0  x10: 0x0000000000000000  x11: 0x000000000000010a
   x12: 0x0000000021455341  x13: 0x0000000000000001  x14: 0x00000000000007fb  x15: 0x00000001eeed0960
   x16: 0xfffffffffffffff4  x17: 0x00000001d848d3ec  x18: 0x0000000107f65370  x19: 0x0000000000000000
   x20: 0x00000001077fd000  x21: 0x00000001066879a0  x22: 0x00000000a1a1a1a1  x23: 0x0000000000000004
   x24: 0x000000011c69f0e8  x25: 0x00000001ef6ee718  x26: 0x000000011c69ef48  x27: 0x00000001074e0bb0
   x28: 0x500000028b0725c0   fp: 0x000000016b430170   lr: 0x6d409681a132cb18
    sp: 0x000000016b430140   pc: 0x00000001a132cd40 cpsr: 0x60000000
   esr: 0x92000046 (Data Abort) byte write Translation fault

Environment

  • SDK Version: 0.3.1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.