EXC_BAD_ACCESS NSKeyedUnarchiver.unarchiveObject iOS 10

Viewed 127

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
0 Answers
Related