AppsFlyerFramework
AppsFlyerFramework copied to clipboard
Crash [AFSDKUserDefaultsStorage incrementInAppCnt]
Report
SDK Version
6.10.0
What did you do?
Included AppsFlyerLib in the iOS app.
What did you expect to happen?
App kept working.
What happened instead?
App occasionally crashes.
Please provide any other relevant information.
SIGTRAP (#0): Application crash: SIGTRAP (Trace/BPT trap)
Thread 26 Crashed:
0 libobjc.A.dylib 0x00000001b699dd94 object_getClass + 48
1 Foundation 0x00000001b7bceec8 _NSKeyValueObservationInfoGetObservances + 248
2 Foundation 0x00000001b7bd5b00 NSKeyValueWillChange + 176
3 Foundation 0x00000001b7c03550 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:] + 464
4 Foundation 0x00000001b7c02678 -[NSObject(NSKeyValueObservingPrivate) _notifyObserversOfChangeFromValuesForKeys:toValuesForKeys:] + 648
5 CoreFoundation 0x00000001bd941000 -[CFPrefsSource forEachObserver:] + 316
6 CoreFoundation 0x00000001bd94646c -[CFPrefsSource _notifyObserversOfChangeFromValuesForKeys:toValuesForKeys:] + 112
7 CoreFoundation 0x00000001bd946368 ___CFPrefsDeliverPendingKVONotificationsGuts_block_invoke + 432
8 CoreFoundation 0x00000001bd949750 __CFDictionaryApplyFunction_block_invoke + 28
9 CoreFoundation 0x00000001bd9719b0 CFBasicHashApply + 148
10 CoreFoundation 0x00000001bd9725d8 CFDictionaryApplyFunction + 320
11 CoreFoundation 0x00000001bd91a254 _CFPrefsDeliverPendingKVONotificationsGuts + 300
12 CoreFoundation 0x00000001bd9709e8 -[_CFXPreferences _deliverPendingKVONotifications] + 96
13 CoreFoundation 0x00000001bd9882f8 __108-[_CFXPreferences(SearchListAdditions) withSearchListForIdentifier:container:cloudConfigurationURL:perform:]_block_invoke + 420
14 CoreFoundation 0x00000001bd973f48 normalizeQuintuplet + 356
15 CoreFoundation 0x00000001bd9707e0 -[_CFXPreferences withSearchListForIdentifier:container:cloudConfigurationURL:perform:] + 152
16 CoreFoundation 0x00000001bd9189d4 -[_CFXPreferences setValue:forKey:appIdentifier:container:configurationURL:] + 128
17 CoreFoundation 0x00000001bd918910 _CFPreferencesSetAppValueWithContainerAndConfiguration + 120
18 Foundation 0x00000001b7c20ef8 -[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 68
19 MyAppYo 0x0000000101817564 -[AFSDKUserDefaultsStorage incrementInAppCnt] + 140
20 MyAppYo 0x0000000101809fe0 __60-[AppsFlyerLib __executeRequestWithEvent:completionHandler:]_block_invoke_3 + 348
21 MyAppYo 0x00000001017f5ed0 __51-[AppsFlyerHTTPClient sendEvent:completionHandler:]_block_invoke.141 + 280
22 libdispatch.dylib 0x00000001c4db4320 _dispatch_call_block_and_release + 32
23 libdispatch.dylib 0x00000001c4db5eac _dispatch_client_callout + 20
24 libdispatch.dylib 0x00000001c4dbd534 _dispatch_lane_serial_drain + 668
25 libdispatch.dylib 0x00000001c4dbe0a4 _dispatch_lane_invoke + 384
26 libdispatch.dylib 0x00000001c4dc8cdc _dispatch_workloop_worker_thread + 648
27 libsystem_pthread.dylib 0x000000021d277ddc _pthread_wqthread + 288
28 libsystem_pthread.dylib 0x000000021d277b7c start_wqthread + 8
Here's a similar issue from 2018 triggered by updating UserDefaults on a background thread.
There, it was suggested to swizzle UserDefaults method and run the change on the main thread. @amit-kremer93 is it still the way to go?
@andr-ggn, does the workaround you proposed here still applies?
This is my workaround:
extension UserDefaults {
static func swizzleInstanceMethodsForAppFlyerWorkaround() {
let originalSelector = #selector(set(_:forKey:) as (UserDefaults) -> (Any?, String) -> Void)
let swizzledSelector = #selector(swizzled_set(_:forKey:))
guard let originalMethod = class_getInstanceMethod(self, originalSelector),
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
else {
assertionFailure("Not able to swizzle UserDefaults methods.")
return
}
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
private extension UserDefaults {
@objc func swizzled_set(_ value: Any?, forKey key: String) {
let appsFlyerInAppCounterKey = "AppsFlyerInAppCounter"
guard
!Thread.isMainThread,
key == appsFlyerInAppCounterKey,
let intValue = value as? Int
else {
swizzled_set(value, forKey: key)
return
}
let diff = intValue - integer(forKey: appsFlyerInAppCounterKey)
DispatchQueue.main.async {
let newValue = self.integer(forKey: appsFlyerInAppCounterKey) + diff
self.swizzled_set(newValue, forKey: key)
}
}
}