4

I’ve been pulling my hair on a weird bug in Xcode 10.2. I’ve had this swift util method to decode JSON objects using ObjectMapper as I can’t call ObjectMapper from ObjectiveC:

@objc static func mapModel(fromClass: AnyClass, jsonDict: [String : Any]) -> Any? {
    guard let mappableClass = fromClass as? Mappable.Type else {
        fatalError("class \(fromClass) is not Mappable")
    }
    return mappableClass.init(JSON: jsonDict)
}

Here's how I call it in ObjectiveC:

FullUser *object = [ModelMapperHelper mapModelFromClass:FullUser.class jsonDict:response.resultData];

I had to use AnyClass because Mappable is not compatible with ObjC. This code has been working fine until I updated to Xcode 10.2.

The last line in the thread in the debugger is swift_checkMetadataState

It’s still working fine with devices on iOS 12.2 and above but it’s crashing with a EXC_BAD_ACCESS at the init() line on iOS 12.1 and below.

If I use the actual class like FullUser.init(JSON: jsonDict) it's all working fine.

Another interesting thing, if I don't pass FullUser.class from objc but set it in swift like so:

@objc static func mapFullUser(jsonDict: [String : Any]) -> Any {
    let fromClass = FullUser.self
    let mappableClass = fromClass as Mappable.Type
    return mappableClass.init(JSON: jsonDict)!
}

it all works fine.

Does anyone have any idea why it’s crashing on older iOS versions and how I can change that code?

Update 1

By just adding print("swift=\(FullUser.self)") before the init() call it's working fine!

I'm starting to think this is a class loader issue. Maybe it has to do with the fact that the project has 2 targets.

Update 2

I removed the 2nd target and it's still crashing.

Update 3

It also crashes if I just pass the class name as a string and get the class from NSClassFromString in swift.

Update 4

It doesn't crash if I decode the parent class User which FullUser inherits.

@objc(User)
class User: NSObject, Mappable {
@objc(FullUser)
class FullUser: User {

Update 5

I tried to call a different static function than init and it's not crashing.

Simon Reggiani
  • 550
  • 10
  • 18
  • Wrapping the `mappableClass.init(JSON: jsonDict)!` inside a try/catch block will probably let you know what exactly failed. – Adis May 31 '19 at 16:16
  • Looks like it's a known issue of Xcode 10.2 (49560721): https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_1_release_notes – Simon Reggiani May 31 '19 at 16:24
  • Could the be the same issue as https://stackoverflow.com/questions/55945140/swift-subclasses-used-in-generics-dont-get-called-when-inheriting-from-nsobject – Simon Reggiani Jun 01 '19 at 21:15
  • seems like 49560721 has been fixed in Xcode 11 and Swift 5.1 but I'm still seeing the crash in that env... – Simon Reggiani Oct 12 '19 at 15:49
  • 4
    `!` means "crash me". It is hard to see what else you expect. – matt Oct 12 '19 at 15:59
  • @matt it crashes without `!` – Simon Reggiani Oct 12 '19 at 16:29
  • Okay I actually have a positive suggestion! I find that some objects don’t cross the bridge properly due to memory management issues. Maybe that’s true of this class object. What if you just pass the string name of the class and let Swift call NSClassFromString? – matt Oct 13 '19 at 19:35
  • Yeah that was a workaround I thought about but wanted to understand the root cause of the issue. And because I don't want to change 30 callers... – Simon Reggiani Oct 14 '19 at 01:45
  • No luck with `NSClassFromString`. Same crash. See Update 3 – Simon Reggiani Oct 14 '19 at 12:34
  • Can you check if your target's `Reflection Metadata Level` is set to `All`, on `Build Settings > Swift Compiler - General`? – vicegax Oct 14 '19 at 14:14
  • Yes it is. I've checked that already :( – Simon Reggiani Oct 14 '19 at 14:17
  • 1
    Can you provide a sample poc project to replicate this issue? – Kamil.S Oct 17 '19 at 18:03
  • Hi Kamil. Thanks for the comment. I tried to replicate this issue with a new project from scratch but couldn't. There are so many moving pieces involved, it's hard to know what should be included... – Simon Reggiani Oct 17 '19 at 22:55
  • I also tried to reproduce the problem, and was not able to see the crash. So maybe more code (context) is needed. – Cristik Oct 18 '19 at 11:02

0 Answers0