MagicalRecord createEntity error in Swift - ios

I have a crash in my Swift project with MagicalRecord - CoreData library : https://github.com/magicalpanda/MagicalRecord
First, I setup MagicalRecord OK in AppDelegate.swift:
MagicalRecord.setupCoreDataStack() //-> This is OK. Don't crash
But, when I want to create a "Contact" entity instance I got a Crash.
My code is the next:
var context = NSManagedObjectContext.MR_contextForCurrentThread() // -> This is OK. Don't crash
var contact = Contact.MR_createInContext(context) // -> CRASH
All compile OK but when the App is running I get the next crash:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an entity named 'MyProject.Contact' in this model.' *** First throw call stack:
(0x27861f77 0x34870c77 0x27590c73 0x9b93d 0x74f28 0x75438 0x2aea6e33 0x2b09acef 0x2b09d19d 0x2b0a79f9 0x2b09ba5b 0x2e106141 0x2782881d 0x27827ae1 0x2782627f 0x27773da1 0x27773bb3 0x2aea0ae7 0x2ae9bc41 0x75ab0 0x75aec 0x34e10aaf)
libc++abi.dylib: terminating with uncaught exception of type NSException
MyProject key is the $(PRODUCT_NAME), how I can fix this?
Kind regards

There is a simple solution to this issue. Just add #objc(ClassName) before the swift NSManagedObject subclass. This allows the Objc side know the right name for the class. Otherwise it will include the module name which is bad in this case because it won't match what you have in your Core Data model. Here's and example from one of my swift projects...
#objc(Plant) public class Plant: NSManagedObject

It seems like MagicalRecord automatically computes the entity name, and does this the wrong way. You can possibly fix this by adding the following code to your Contact class:
class func entityName() -> String {
return "Contact"
}

In Swift, you likely need to set the class for your entity to MyProject.Contact for it to be found automatically though the model. In the Entity inspector on the right of the Entity modeler, you can change the class name there.

The solution of Guido Hendriks with an extension to support all managed objects:
extension NSManagedObject {
class func entityName() -> String {
return NSStringFromClass(self).componentsSeparatedByString(".").last!
}
}

Thank you for the answers. I Think that Guido Hendriks's is a good answer. I tried casademora answer but I didn't got the App work.
Finally I have changed the CoreData classes language (Contact Class) from Swift to Objective-C and now the MagicalRecord library works fine!
Thank you!

I had to deal with the same problem and took me a while to figure out how to...
Thanks #casademora I created the classes as Obj-C ones and imported the headers in bridging-header of my swift project.
Select your .xcdatamodeld file
Editor
Create NSManagedObject Subclass
Select your data model and entities
Save the file as an Objective-C class
Here you go with a nice picture:
And in the prefix header file:
#ifndef DBSwiftTest_Bridging_Header_h
#define DBSwiftTest_Bridging_Header_h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "DKDBManager.h" // My database manager
#import "Runner.h" // My model in this example
#endif

You can create your entity classes in objective-c and exposing them via bridging header to swift. That way crash dissappears

I have the same issue. Here is what i did to solve it:
Step 1: As Guido Hendriks mentioned in his answer
It seems like MagicalRecord automatically computes the entity name, and does this the wrong way. You can possibly fix this by adding the following code to your Contact class"
class func entityName() -> String {
return "Contact"
}
Step 2: In your DataModel, change the Class of the Entity from Contact to ProjectName.Contact

Related

{Module_name}-Swift.h file not working well only in Swift 4 projects unlike Swift 3.2

Anyone faced problems in {Module_name}-Swift.h file for Swift 4 projects? I've noticed -Swift.h autogenerated file not working well with Swift 4 syntax unlike Swift 3.2!.
For example, -Swift.h file doesn't contain all variables and methods which implemented in the custom Swift classes which inherited from NSObject class!
I've used #objc and #classkeywords but no way.
I don't get any errors! the problem is if I've created a class like this:
import Foundation
class Utils: NSObject {
let abc: String?
func xyz() {
print("")
}
}
and navigate to {Module_name}-Swift.h I see something like that:
SWIFT_CLASS("_TtC3{Module_name}5Utils")
#interface Utils : NSObject
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
#end
Problem
Both let abc: String? and func xyz() have been never included in {Modue_name}-Swift.hfile!
I think in Swift 4 you have to mark a lot more things #objc (nothing implicit anymore) but other than that it should just be in there.
You can all check it to confirm class name in .h file like:
#class filename;
The generated file {Module}-Swift.h does not contain your variables and methods, the file is generated to give you access to the Module namespace.
The actual interface for the generated module lives in Module.swiftmodule/arm64.swiftmodule (depending on built architecture).
More information on its contents:
https://bugs.swift.org/browse/SR-2502
https://lists.swift.org/pipermail/swift-users/Week-of-Mon-20160111/000827.html
https://stackoverflow.com/a/24396175/1755720
however... the format is not documented anywhere and is subject to change. A good starting point would be to look in include/swift/Serialization/ModuleFormat.h
As to why it's not working - Swift 4 has a migration process, please ensure you have followed it: https://swift.org/migration-guide-swift4/
Xcode will pick up most things ... but it won't get everything!
And why do you need header files for Swift classes? You just can mark swift class as #objc and you will be able to reach all its properties.

Swift3 CoreData crash on iOS9 device

I have CoreData app that is perfectly working on iOS10, written in Swift3, supporting iOS 8.4 and above.
When I try to run it on iOS 9.3.5 I'm getting error:
2016-10-07 17:47:20.596 FormApp[710:179733] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSSet intersectsSet:]: set argument is not an NSSet'
crashing on line:
form.addToOpenQuestions(openQuestion)
I have added #objc() to managed object classes. Then I'm getting new error:
CoreData: warning: Unable to load class named 'FormApp.Form' for entity 'Form'. Class not found, using default NSManagedObject instead.
It is happening on line:
let form = NSEntityDescription.insertNewObject(forEntityName: "Form", into: managedObjectContext) as! Form
My config:
All classes were generated by Xcode. I have tried deleting Module and all configurations. Anyone have idea how to make it work?
For some reason NSSet is expected, but your NSManagedObject code has NSOrderedSet, which is a subclass of NSObject. Try to remove "Arrangment: Ordered" checkmark in your core data model and refactor those relationships to NSSet.
Not sure why this happens in iOS 10 but not in iOS 9 though.
P.S. Perhaps you should reconsider your Core Data model? It looks like your Open/Closed questions are going to change their status. If so, I would recommend to make one Question entity with closed bool or status int.
I was having the same issue with iOS 9.3
The issue was same as mention by #alex above and i have solve as below
if #available(iOS 11.0, *) {
// use iOS 11-only feature
YOUR_CLASS.insertIntoClosedQuestion(YOUR_OBJECT, at: index)
} else {
// handle older versions
let orderset:NSMutableOrderedSet = Form.closeQuestion as! NSMutableOrderedSet
orderset.insert(YOUR_OBJECT, at: index)
YOUR_CLASS.addToClosedQuestion(orderset)
}
Hope it will helpful to others.

I want to call a class function written in Swift from the AppDelegate (which is in Objective C). What am I doing wrong?

I have a swift file "SomeController.swift" it is like this:
import Foundation
func performSomeStuff() {
println("Performing stuff")
}
Now in the app delegate, I am trying to do this: (note that the swift bridging header is imported)
[SomeController performSomeStuff]
But its not working.
I have also tried this:
import Foundation
class SomeController:NSObject {
class func performSomeStuff() {
println("Performing stuff")
}
}
But it still fails.
What is the correct way?
Add:
#objc
before the class keyword in your swift code so it will be:
#objc class SomeStuff: NSObject {
}
Also add #obj in front of any function that you want to call.
Then in your app delegate make sure to use #import "projectName-Swift.h"
Are you able to access "SomeController" class in objective-c, if not then you firstly need to add "${ProjectName}-Swift.h file and add Swift compilation support in Build settings as:
And for accessing methods from Swift to Objective-C, add
import Foundation
class SomeStuff:NSObject {
#objc class func performSomeStuff() {
println("Performing stuff")
}
}
before functions name.
In some cases, you need finer grained control over how your Swift API is exposed to Objective-C. You can use the #objc attribute if your Swift class doesn’t inherit from an Objective-C class, or if you want to change the name of a symbol in your interface as it’s exposed to Objective-C code.
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html
Ok, So I figured it out. First, here's the correct way. Its like some of you said:
In the swift file, I have it like this:
class MyController:NSObject{
class func performTask {
// Here my task is running.
}
}
Then in the app delegate, I just import the swift header file. And do this:
[MyController performTask];
Now for the part I had wrong. It was an error on my part, but maybe it'll be useful to someone else out there.
When I first created the first swift file, I had placed it inside a folder within the my Source folder. But when I started having multiple swift files, I moved the bridging header outside that folder and into the main Source folder (just for organising).
The problem was, it did not give me a direct error to tell me what was the problem. I had to check the issue navigator to identify the problem.
Hope this helps someone out there.

'Use of Unresolved Identifier' in Swift

So I have been making an app, and everything has been working great. But today I made a new class like usual and for some reason in this class I can't access Public/Global variable from other classes. All the other classes can, but now when ever I try to make a new class I can't. How would this be fixed?
I am using Swift and Xcode 6.
Working Class:
import UIKit
import Foundation
import Parse
import CoreData
var signedIn = true
class ViewController: UIViewController {
New Class:
import UIKit
class NewClass: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
signedIn = false
}
But on signedIn = false
I get the error:
use of unresolved identifier "signedIn"
One possible issue is that your new class has a different Target or different Targets from the other one.
For example, it might have a testing target while the other one doesn't. For this specific case, you have to include all of your classes in the testing target or none of them.
Once I had this problem after renaming a file. I renamed the file from within Xcode, but afterwards Xcode couldn't find the function in the file. Even a clean rebuild didn't fix the problem, but closing and then re-opening the project got the build to work.
'Use of Unresolved Identifier' in Swift my also happen when you forgot to import a library. For example I have the error:
In which I forgot the UIKit
import UIKit
Sometimes the compiler gets confused about the syntax in your class. This happens a lot if you paste in source from somewhere else.
Try reducing the "unresolved" source file down to the bare minimum, cleaning and building. Once it builds successfully add all the complexity back to your class.
This has made it go away for me when re-starting Xcode did not work.
Another place I've seen this error is when your project has multiple targets AND multiple bridging headers. If it's a shared class, make sure you add the resource to all bridging headers.
A good tip to is to look in the left Issue Navigator panel; the root object will show the target that is issuing the complaint.
For me this error happened because I was trying to call a nested function. Only thing I had to do to have it fixed was to bring the function out to a scope where it was visible.
In my case, I had an Object-C file which was also in the same Target Membership. I fixed by adding #import "YourObjectCFileHeader.h" inside file Bridging-Header.h
Because you haven't declared it. If you want to use a variable of another class you must use
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var DestViewController : ViewController = segue.destinationViewController as ViewController
DestViewController.signedIn = false
}
You have to put this code at the end of the NewClass code
Your NewClass inherits from UIViewController. You declared signedIn in ViewController. If you want NewClass to be able to identify that variable it will have to be declared in a class that your NewClass inherits from.
I got this error for Mantle Framework in my Objective-Swift Project.
What i tried is ,
Check if import is there in Bridging-Header.h file
Change the Target Membership for Framework in Mantle.h file as shown in below screenshot.
Toggle between Private Membership first build the project , end up with errors.
Then build the project with Public Membership for all the frameworks appeared for Mantle.h file, you must get success.
It is just a bug of building with multiple framework in Objective-C Swift project.
If this is regarding a class you created, be sure that the class is not nested.
F.e
A.swift
class A {
class ARelated {
}
}
calling var b = ARelated() will give 'Use of unresolved identifier: ARelated'.
You can either:
1) separate the classes if wanted on the same file:
A.swift
class A {
}
class ARelated {
}
2) Maintain your same structure and use the enclosing class to get to the subclass:
var b = A.ARelated
I did a stupid mistake. I forgot to mention the class as public or open while updating code in cocoapod workspace.
Please do check whether accesor if working in separate workspace.
You forgot to declare the variable. Just put var in front of signedIn = false
My issue was calling my program with the same name as one of its cocoapods. It caused a conflict. Solution: Create a program different name.
This is not directly to your code sample, but in general about the error. I'm writing it here, because Google directs this error to this question, so it may be useful for the other devs.
Another use case when you can receive such error is when you're adding a selector to method in another class, eg:
private class MockTextFieldTarget {
private(set) var didCallDoneAction = false
#objc func doneActionHandler() {
didCallDoneAction = true
}
}
And then in another class:
final class UITextFieldTests: XCTestCase {
func testDummyCode() {
let mockTarget = MockTextFieldTarget()
UIBarButtonItem(barButtonSystemItem: .cancel, target: mockTarget, action: MockTextFieldTarget.doneActionHandler)
// ... do something ...
}
}
If in the last line you'd simply call #selector(cancelActionHandler) instead of #selector(MockTextFieldTarget.cancelActionHandler), you'd get
use of unresolved identifier
error.

Objective-C project with Swift UIApplication subclass. Error: class not loaded

I have a project written in Objective-C and I just added a UIApplication subclass using Swift: RMFApplication.swift (implementation at end of post). However, I am getting this error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unable to instantiate the
UIApplication subclass instance. No class named RMFApplication is
loaded.'
In my info.plist I correctly specified the name under
NSPrincipalClass, and double checked it.
I read this answer and then looked in my own main.m which says: return UIApplicationMain(argc, argv, nil, NSStringFromClass([RMFAppDelegate class]));.
The docs for UIApplicationMain say that if nil is specified as the thrid value then UIApplication is assumed, but why then does my error message include my custom class name? I have to assume nil means it will read the info.plist value.
Note: Subclassing UIApplication worked well with RMFApplication.h and
RMFApplication.m. The only thing that changed was the renaming of
those files and the addition of a RMFApplication.swift file, which
compiles with no warnings:
import UIKit
class RMFApplication: UIApplication {
override func openURL(url: NSURL) -> Bool
{
println(url.description)
return false;
}
}
I am aware that I can just continue using Objective-C, but I would like to try and migrate to Swift unless the two really don't play well together.
Maybe that's because it uses NSStringFromClass or something, so that in Swift RMFApplication is "mangled" and becomes something like "somePrefix"RMFApplication (or whatever different from just "RMFApplication").
You could try this:
#objc(RMFApplication) class RMFApplication: UIApplication
And then NSStringFromClass will return just "RMFApplication".

Resources