Swift3 CoreData crash on iOS9 device - ios

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.

Related

SharkORM Encrypted properties issue in iOS Swift 3

I'm working on iOS project with DB, I am using SharkORM and integrate it to my project using cocoa pods, my project is built using Swift 3.
Everything is working perfectly, but now I need to add encrypted values to the DB and in order to test it I added a very simple code,
I created a "User" class in which I defined a "test" property, this property is of type Double:
dynamic var test: Double = 0;
I also added the following code to the class to define "test" as encrypted property:
override class func encryptedPropertiesForClass() -> [Any]! {
return ["test"]
}
in order to read/write this property I did the following:
print(User.currentUser.test)
User.currentUser.test = 10
User.currentUser.commit()
print(User.currentUser.test)
Please note that current user is a singleton instance and it is being read from the DB. However, I'm getting the following exception:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SRKEncryptedObject doubleValue]: unrecognized selector sent to instance
Any idea why this is happening? thanks in advance.

UIImage+ResizeMagick | NSInvalidArgumentException | iOS | Swift

I'm using "UIImage+ResizeMagick" (iOS api by some developer for resizing image written in obj-c) in my swift project, but facing issues and getting the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIImage resizedImageByMagick:]: unrecognized selector sent to instance 0x7fe74c2065c0'
I know this error occurs when that function doesn't exists in that particular class or if we pass wrong parameters while calling the function but i don't think it's the case with my code (if i'm not wrong)
This class is written as: "UIImage(ResizeMagick)" and as per my knowledge it's a category so i can use the methods with every UIImage object. I've imported it in my class as #import "UIImage+ResizeMagick.h" and using it as:
UIImage *image = [UIImage imageNamed:#"validate-icon-tick.png"];
image = [image resizedImageByMagick:#"200x200"];
I'm using multiple libraries in my project that are written in obj-c but i'm using bridging header for this purpose. May be the problem with ResizeMagick is because of extensions vs categories difference in obj-c and swift.
Kindly tell me what i'm doing wrong or if is it possible or not. Thanks.
Fixed the issue for using extension (cocopods) in swift.
I've added #import <UIImage-ResizeMagick/UIImage+ResizeMagick.h> in my bridging header file. In controller i've used the methods of this extension as:
let image = oldImage.resizedImageByMagick("200x200")
Extensions vs Categories (in swift and objective-c) are well explained over here:stack overflow post link

XCode7 Core Data: Fetch for objects etc

I created an iOS8 application and updated it to XCode7. I have a couple of problems after I recreated the NSManagedObject.
First I get an error, if I fetch for contacts and iterate over them:
let contacts = try self.managedObjectContext.executeFetchRequest(request) as! [Contact]
for contact in contacts{
//--> EXC_BAD_INSTRUCION
}
Contact is my NSManagedObject. I do not get any compiler error or warning.
Second: I get this warning:
CoreData: warning: Unable to load class named 'MyAppName.Contact' for entity 'Contact'. Class not found, using default NSManagedObject instead.
What can cause this? The #objc(Contact) in Contact has already been generated bei XCode and now I can't set the className MyAppName.Contact in CoreData-editor. Any suggestion?
Finally found it. All the other tips are not working, because Apple has changed it with XCode7.
Now XCode creates #(Classname) in the NSManagedSubclass. This needs to be commented out (beta1 and beta2). Then XCode can find your class.

MagicalRecord createEntity error in Swift

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

Writing an iOS 8 share extension without a storyboard

Does anyone know of a good way to write an iOS 8 share extension without the MainInterface.storyboard that comes with the template?
When I delete the file or remove the NSExtensionMainStoryboard from Info.plist, the extension stops working (nothing happens when you tap on the button in the share pane). We tried replacing NSExtensionMainStoryboard with NSExtensionPrincipalClass which also didn't work.
Any ideas?
Figured it out!
Turns out there's a weird module naming thing going on in Swift, so you can fix it by adding an #objc name to the class:
#objc(PrincipalClassName)
class PrincipalClassName: UIViewController {
...
and then set the NSExtensionPrincipalClass key to PrincipalClassName.
Instead of the #objc hack, the proper way to do it in Swift is to include the module name in NSExtensionPrincipalClass, i.e.,
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).ActionViewController</string>
(Documenting the error otherwise:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSDictionaryM setObject:forKey:]: object cannot be nil (key: ...)'
Hopefully will help someone who run into this error in the future.)
Found the answers from these answers combined Answer 1 and Answer 2.
For Objective-C you will have to put the following in the info.plist of the App extension:
NSExtensionPrincipalClass and make sure that it is under NSExtension Dict
So full answer should be like this , in my case ActionViewController is the App extension viewController
Can't add a comment but it is no longer NSPrincipalClass rather it is NSExtensionPrincipalClass

Resources