I've been researching for similar posts but found no solution to it. I have a legacy User object (inside a recently created framework), that is stored to defaualts using NSCoding protocol via Objective-C code.
+ (void)setUserDefaultsObject:(id)object withKey:(NSString*)key
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (object) {
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:object];
[defaults setObject:encodedObject forKey:key];
} else {
[defaults setObject:nil forKey:key];
}
}
When I try to get this object inside a framework using Swift 5 code it crashes on the self.init, only on iOS 10.x.x versions.
import Foundation
import ObjectMapper
@objc
public final class User: NSObject, Mappable, NSCoding, NSSecureCoding {
// Variables and methods
@objc override public init() {
super.init()
}
required public init?(map: Map) {
}
public func mapping(map: Map) {
...
}
public static var supportsSecureCoding: Bool {
return true
}
public enum CodingKeys: String, CodingKey {
case json
}
required convenience public init?(coder aDecoder: NSCoder) {
guard let json = aDecoder.decodeObject(of: NSString.self, forKey: CodingKeys.json.rawValue) as String? else {
return nil
}
self.init(JSONString: json) // This is where it crashes
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(self.toJSONString(), forKey: CodingKeys.json.rawValue)
}
}
This is the code to retrieve the user from defaults.
static var userLogged: User? {
guard let encodedUser: Data = PreferenceService.getObject(forKey: .user) else {
return nil
}
if #available(iOS 11.0, *) {
do {
return try NSKeyedUnarchiver.unarchivedObject(ofClass: User.self, from: encodedUser)
} catch {
return nil
}
} else {
return NSKeyedUnarchiver.unarchiveObject(with: encodedUser) as? User
}
}
And finally, this is the stack trace I got from Crashlytics.
Crashed: com.apple.main-thread
0 libswiftCore.dylib 0x102389c80 swift_checkMetadataState + 376
1 libswiftCore.dylib 0x102389c60 swift_checkMetadataState + 344
2 libswiftCore.dylib 0x1023556bc type metadata completion function for ClosedRange<>.Index + 3476
3 libswiftCore.dylib 0x10238ce24 swift::MetadataCacheEntryBase<(anonymous namespace)::GenericCacheEntry, void const*>::doInitialization(swift::ConcurrencyControl&, swift::MetadataCompletionQueueEntry*, swift::MetadataRequest) + 276
4 libswiftCore.dylib 0x102384168 swift_getGenericMetadata + 1196
5 libswiftCore.dylib 0x1022045f8 type metadata accessor for Optional + 306940
6 ObjectMapper 0x10155b8b0 Mappable.init(JSONString:context:) + 60 (<compiler-generated>:60)
7 ModelsModule 0x101fd5928 User.init(coder:) + 124 (User.swift:124)
8 ModelsModule 0x101fd59f8 @objc User.init(coder:) + 14044 (<compiler-generated>:14044)
9 Foundation 0x1870fa420 _decodeObjectBinary + 2076
10 Foundation 0x1870f9b58 _decodeObject + 308
11 Foundation 0x1870f8d84 +[NSKeyedUnarchiver unarchiveObjectWithData:] + 88
12 NetworkModule 0x1020c17b8 specialized static UserService.userLogged.getter + 92 (UserService.swift:92)
13 NetworkModule 0x1020d2094 specialized static BaseApiService.setupRequestHeaders(environment:) + 118 (BaseApiService.swift:118)
14 NetworkModule 0x1020cb860 BaseApiService.request(_:path:body:params:) + 36512 (<compiler-generated>:36512)
15 NetworkModule 0x1020c026c UserService.auth(refreshToken:) + 51 (BaseApiService.swift:51)
16 Andjoy 0x100260bdc LaunchScreenViewModel.authUser() + 69 (LaunchScreenViewModel.swift:69)
17 Andjoy 0x1000a546c LaunchScreenViewController.viewDidLoad() + 44 (LaunchScreenViewController.swift:44)
18 Andjoy 0x1000a58f8 @objc LaunchScreenViewController.viewDidLoad() + 4296349944 (<compiler-generated>:4296349944)
19 UIKit 0x18c7d9f9c -[UIViewController loadViewIfRequired] + 1036
20 UIKit 0x18c8920c4 -[UINavigationController _layoutViewController:] + 72
21 UIKit 0x18c891f9c -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 416
22 UIKit 0x18c8912cc -[UINavigationController _startTransition:fromViewController:toViewController:] + 144
23 UIKit 0x18c890d00 -[UINavigationController _startDeferredTransitionIfNeeded:] + 856
24 UIKit 0x18c8908b4 -[UINavigationController __viewWillLayoutSubviews] + 64
25 UIKit 0x18c890818 -[UILayoutContainerView layoutSubviews] + 188
26 UIKit 0x18c7d7158 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1200
27 QuartzCore 0x1899c7274 -[CALayer layoutSublayers] + 148
28 QuartzCore 0x1899bbde8 CA::Layer::layout_if_needed(CA::Transaction*) + 292
29 QuartzCore 0x1899bbca8 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
30 QuartzCore 0x189937360 CA::Context::commit_transaction(CA::Transaction*) + 252
31 QuartzCore 0x18995e3c0 CA::Transaction::commit() + 504
32 QuartzCore 0x18995ee8c CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 120
33 CoreFoundation 0x1866589a0 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
34 CoreFoundation 0x186656628 __CFRunLoopDoObservers + 372
35 CoreFoundation 0x186586db4 CFRunLoopRunSpecific + 456
36 UIKit 0x18c84445c -[UIApplication _run] + 652
37 UIKit 0x18c83f130 UIApplicationMain + 208
38 Andjoy 0x10001e598 main + 28 (G4LAppDelegate.swift:28)
39 libdyld.dylib 0x18559559c start + 4