Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Importing data using Swift 3 #1294

Open
ro22e0 opened this issue Mar 16, 2017 · 7 comments
Open

Importing data using Swift 3 #1294

ro22e0 opened this issue Mar 16, 2017 · 7 comments
Labels

Comments

@ro22e0
Copy link

ro22e0 commented Mar 16, 2017

Hello,

I try to import data from JSON array like this :

let json = JSON(value)
let data: [[String: Any]] = self.transformJson(json)
MagicalRecord.saveInBackground({ (localContext) in
     User.mr_import(from: data, in: localContext)
})

Using Swift 3

The problem is mr_import call MR_importFromObject:inContext: instead of MR_importFromArray:inContext:

Here's the exception :

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<_SwiftValue 0x6080000c9e60> valueForUndefinedKey:]: this class is not key value coding-compliant for the key id.'
*** First throw call stack:
(
0 CoreFoundation 0x0000000109ae4d4b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010cf4a21e objc_exception_throw + 48
2 CoreFoundation 0x0000000109ae4c99 -[NSException raise] + 9
3 Foundation 0x000000010cb247c5 -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 226
4 Foundation 0x000000010ca5060b -[NSObject(NSKeyValueCoding) valueForKey:] + 283
5 Foundation 0x000000010ca53eec -[NSArray(NSKeyValueCoding) valueForKey:] + 467
6 Foundation 0x000000010ca503e8 -[NSArray(NSKeyValueCoding) valueForKeyPath:] + 448
7 MagicalRecord 0x000000010a968ce8 -[NSObject(MagicalRecord_DataImport) MR_lookupKeyForAttribute:] + 232
8 MagicalRecord 0x000000010a968efe -[NSObject(MagicalRecord_DataImport) MR_valueForAttribute:] + 62
9 MagicalRecord 0x000000010a95b7c7 _75+[NSManagedObject(MagicalRecord_DataImport) MR_importFromObject:inContext:]block_invoke + 135
10 CoreData 0x000000010d4519a7 developerSubmittedBlockToNSManagedObjectContextPerform + 199
11 CoreData 0x000000010d45185f -[NSManagedObjectContext performBlockAndWait:] + 255
12 MagicalRecord 0x000000010a95b5db +[NSManagedObject(MagicalRecord_DataImport) MR_importFromObject:inContext:] + 331
13 Kairos 0x0000000108e057ce TFFZFV6Kairos8DataSync10fetchUsersFFOS_13StatusRequestT_T_U_FGV9Alamofire12DataResponseP__T_U_FCSo22NSManagedObjectContextT + 158
14 Kairos 0x0000000108dc9ecc TTRXFo_oCSo22NSManagedObjectContext__XFdCb_dS
+ 60
15 MagicalRecord 0x000000010a953671 __73+[MagicalRecord(ActionsDeprecated) saveInBackgroundWithBlock:completion:]_block_invoke + 129
16 CoreData 0x000000010d4519a7 developerSubmittedBlockToNSManagedObjectContextPerform + 199
17 libdispatch.dylib 0x000000010e9740cd _dispatch_client_callout + 8
18 libdispatch.dylib 0x000000010e951e17 _dispatch_queue_serial_drain + 236
19 libdispatch.dylib 0x000000010e952b4b _dispatch_queue_invoke + 1073
20 libdispatch.dylib 0x000000010e95302b _dispatch_queue_override_invoke + 683
21 libdispatch.dylib 0x000000010e955385 _dispatch_root_queue_drain + 720
22 libdispatch.dylib 0x000000010e955059 _dispatch_worker_thread3 + 123
23 libsystem_pthread.dylib 0x000000010ed23712 _pthread_wqthread + 1299
24 libsystem_pthread.dylib 0x000000010ed231ed start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException

@ro22e0 ro22e0 changed the title Importing data Importing data using Swift 3 Mar 16, 2017
@rugheid
Copy link

rugheid commented Jun 10, 2017

If you are still interested in what the problem is, than here is the answer:
The problem is that your export of the JSON object uses Swift representations internally. When you use the processed SwiftyJSON values, this will almost always be the case, unless you transform them yourself to the Objective-C equivalents. If you are using the dictionaryValue-like methods of SwiftyJSON, then there are definitely JSON objects inside and they use Swift values. You could modify your transformJson to do this transformation. For me however, since the JSON data was already in the correct format, the easiest way was using the raw values inside the JSON object:

guard let array = json.rawValue as? [[AnyHashable: Any]] else { return nil }
// mr_import here using array

I use [[AnyHashable: Any] here, since that is what the Objective-C bridged method expects.

@ro22e0
Copy link
Author

ro22e0 commented Jun 15, 2017

Wow thanks !

@Coeur
Copy link
Collaborator

Coeur commented Jun 21, 2019

You can disambiguate which obj-c selector is called by casting your parameters:

// will call MR_importFromArray
User.mr_import(from: data as [[AnyHashable : Any]], in: localContext)
// will call MR_importFromObject
User.mr_import(from: data as Any, in: localContext)

@Coeur Coeur closed this as completed Jun 21, 2019
@EzDream
Copy link

EzDream commented Jul 3, 2019

You can disambiguate which obj-c selector is called by casting your parameters:

// will call MR_importFromArray
User.mr_import(from: data as [[AnyHashable : Any]], in: localContext)
// will call MR_importFromObject
User.mr_import(from: data as Any, in: localContext)

Code in Swift didn’t distingush the function name between MR_importFromArray and MR_importFromObject. Your code still cannot work because it’s always recognize as the MR_importFromObject function. This problem is depressing.

@Coeur
Copy link
Collaborator

Coeur commented Jul 3, 2019

@EzDream I tested the code myself, with NSLog and breakpoints: it does call MR_importFromArray when the type is explicitly [[AnyHashable : Any]]. Maybe you didn't clean the DerivedData or something.

@Coeur
Copy link
Collaborator

Coeur commented Jul 3, 2019

We could eventually add an explicit distinct naming with NS_SWIFT_NAME, as described in https://developer.apple.com/documentation/swift/objective-c_and_c_code_customization/renaming_objective-c_apis_for_swift.

@Coeur Coeur self-assigned this Jul 3, 2019
@Coeur Coeur reopened this Jul 3, 2019
@Coeur
Copy link
Collaborator

Coeur commented Oct 28, 2019

Sorry, I have no more plans to perform a renaming for now, so I'll unassign myself.
Pull request welcome.

@Coeur Coeur removed their assignment Oct 28, 2019
@Coeur Coeur added the Easy label Oct 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants