Reputation: 233
I'm working on a iOs program in Swift, I'm using Core Data, I tried to found how to have a auto increment id, I found this:
But no issues here, so I tried to see how to write a self auto increment attribute:
I added a new attribute in my .xcdatamodeld
file named "id", I found a solution in Objective-C:
https://stackoverflow.com/a/22503259/5315947
But I don't know how to parse it into Swift2
My code:
let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDel.managedObjectContext
let newDemande = NSEntityDescription.insertNewObjectForEntityForName("Demandes", inManagedObjectContext: context)
newDemande.setValue(soapRequest.xmlString, forKey: "xml")
newDemande.setValue(1, forKey: "statutenvoie")
do {
try context.save()
} catch {
print("erreur data")
}
do {
let request = NSFetchRequest(entityName: "Demandes")
let results = try context.executeFetchRequest(request)
if results.count > 0 {
for item in results as! [NSManagedObject]{
let xml = item.valueForKey("xml")
let statutenvoie = item.valueForKey("statutenvoie")
print(item.objectID)
print(xml!, statutenvoie!)
}
}
} catch {
print("erreur data")
}
UUID error:
code:
let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDel.managedObjectContext
let newDemande = NSEntityDescription.insertNewObjectForEntityForName("Demandes", inManagedObjectContext: context)
newDemande.setValue(NSUUID().UUIDString, forKey: "id")
newDemande.setValue(soapRequest.xmlString, forKey: "xml")
newDemande.setValue(1, forKey: "statutenvoie")
do {
try context.save()
} catch {
print("erreur data")
}
do {
let request = NSFetchRequest(entityName: "Demandes")
let results = try context.executeFetchRequest(request)
if results.count > 0 {
for item in results as! [NSManagedObject]{
let id = item.valueForKey("id")
let xml = item.valueForKey("xml")
let statutenvoie = item.valueForKey("statutenvoie")
// print(item.objectID)
print(id!, xml!, statutenvoie!)
}
}
} catch {
print("erreur data")
}
error:
2016-01-11 16:33:18.921 ...[2694:108875] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "id"; desired type = NSNumber; given type = __NSCFString; value = 781EFF10-A9F1-4710-98C1-6D342B2EB480.'
*** First throw call stack:
(
0 CoreFoundation 0x0000000110a2be65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001132f8deb objc_exception_throw + 48
2 CoreData 0x00000001105c77b0 _PFManagedObject_coerceValueForKeyWithDescription + 2864
3 CoreData 0x000000011059f621 _sharedIMPL_setvfk_core + 177
4 ... 0x000000010ff690e5 _TFC7...29DemandeGratuiteViewController7ValiderfS0_FPSs9AnyObject_T_ + 4757
5 ... 0x000000010ff6aaa6 _TToFC7...29DemandeGratuiteViewController7ValiderfS0_FPSs9AnyObject_T_ + 54
6 UIKit 0x0000000112285e73 _UIGestureRecognizerSendTargetActions + 153
7 UIKit 0x00000001122824e5 _UIGestureRecognizerSendActions + 162
8 UIKit 0x00000001122804e2 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 843
9 UIKit 0x00000001122889a0 ___UIGestureRecognizerUpdate_block_invoke904 + 79
10 UIKit 0x000000011228883e _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 342
11 UIKit 0x0000000112276101 _UIGestureRecognizerUpdate + 2634
12 UIKit 0x0000000111e0df8a -[UIWindow _sendGesturesForEvent:] + 1137
13 UIKit 0x0000000111e0f1c0 -[UIWindow sendEvent:] + 849
14 UIKit 0x0000000111dbdb66 -[UIApplication sendEvent:] + 263
15 UIKit 0x0000000111d97d97 _UIApplicationHandleEventQueue + 6844
16 CoreFoundation 0x0000000110957a31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
17 CoreFoundation 0x000000011094d95c __CFRunLoopDoSources0 + 556
18 CoreFoundation 0x000000011094ce13 __CFRunLoopRun + 867
19 CoreFoundation 0x000000011094c828 CFRunLoopRunSpecific + 488
20 GraphicsServices 0x0000000114c2dad2 GSEventRunModal + 161
21 UIKit 0x0000000111d9d610 UIApplicationMain + 171
22 ... 0x000000010ff352cd main + 109
23 libdyld.dylib 0x0000000113e0a92d start + 1
24 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Error:
2016-01-12 09:13:03.726 ...[576:7439] CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/informatiqueresponis/Library/Developer/CoreSimulator/Devices/314EFA4E-CC21-45A0-B3FD-FA486D52BB99/data/Containers/Data/Application/B0AB216F-D9B4-408D-ADB5-92BE2D333F62/Documents/SingleViewCoreData.sqlite options:(null) ... returned error Error Domain=NSCocoaErrorDomain Code=134100 "(null)" UserInfo={metadata={
NSPersistenceFrameworkVersion = 641;
NSStoreModelVersionHashes = {
Demandes = <e6fa8ed7 47097048 95c90274 cbc26ea7 decd6ea3 12e0df98 cd0d3cec da84d5ff>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "7C53DEAF-C47E-446B-913E-060946C728B0";
"_NSAutoVacuumLevel" = 2;
}, reason=The model used to open the store is incompatible with the one used to create the store} with userInfo dictionary {
metadata = {
NSPersistenceFrameworkVersion = 641;
NSStoreModelVersionHashes = {
Demandes = <e6fa8ed7 47097048 95c90274 cbc26ea7 decd6ea3 12e0df98 cd0d3cec da84d5ff>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "7C53DEAF-C47E-446B-913E-060946C728B0";
"_NSAutoVacuumLevel" = 2;
};
reason = "The model used to open the store is incompatible with the one used to create the store";
}
2016-01-12 09:13:03.730 ...[576:7439] Unresolved error Error Domain=YOUR_ERROR_DOMAIN Code=9999 "Failed to initialize the application's saved data" UserInfo={NSLocalizedDescription=Failed to initialize the application's saved data, NSLocalizedFailureReason=There was an error creating or loading the application's saved data., NSUnderlyingError=0x7fded60cdae0 {Error Domain=NSCocoaErrorDomain Code=134100 "(null)" UserInfo={metadata={
NSPersistenceFrameworkVersion = 641;
NSStoreModelVersionHashes = {
Demandes = <e6fa8ed7 47097048 95c90274 cbc26ea7 decd6ea3 12e0df98 cd0d3cec da84d5ff>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "7C53DEAF-C47E-446B-913E-060946C728B0";
"_NSAutoVacuumLevel" = 2;
}, reason=The model used to open the store is incompatible with the one used to create the store}}}, [NSLocalizedDescription: Failed to initialize the application's saved data, NSLocalizedFailureReason: There was an error creating or loading the application's saved data., NSUnderlyingError: Error Domain=NSCocoaErrorDomain Code=134100 "(null)" UserInfo={metadata={
NSPersistenceFrameworkVersion = 641;
NSStoreModelVersionHashes = {
Demandes = <e6fa8ed7 47097048 95c90274 cbc26ea7 decd6ea3 12e0df98 cd0d3cec da84d5ff>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "7C53DEAF-C47E-446B-913E-060946C728B0";
"_NSAutoVacuumLevel" = 2;
}, reason=The model used to open the store is incompatible with the one used to create the store}]
(lldb)
Upvotes: 0
Views: 5798
Reputation: 1514
Still confusing with the example you gave in the comment. My answer is based on my understand that you want an auto increase field - id
, when next time you insert a new entry.
If you have two fields, i.e. xmlString
& id
. Then first you do everytime is a fetch request with SortDescriptor
and setFetchLimit = 1
. If the result is empty, you insert a new entry with id = 1
. Otherwise, insert a new entry with id = oldId + 1
.
I intentionally doesn't provide any code, because I'm not sure what you really want.
BTW, you'd better to use custom model, i.e. NSManagedObject
generated by XCode
, rather than the current newDemande.setValue(value, forKey: "key")
EDIT
Example code provided:
// Initialize Fetch Request
let fetchRequest = NSFetchRequest(entityName: "Demandes")
// Sort Descriptor
var idDescriptor: NSSortDescriptor = NSSortDescriptor(key: "id", ascending: false)
fetchRequest.sortDescriptors = [idDescriptor] // Note this is a array, you can put multiple sort conditions if you want
// Set limit
fetchRequest.fetchLimit = 1
var newId = 0; // Default to 0, so that you can check if do catch block went wrong later
do {
let results = try self.managedObjectContext.executeFetchRequest(fetchRequest)
//Compute the id
if(results.count == 1) newId = results[0].id + 1 // slightly odd notation here, .id can be used if you use custom model. or you can use .valueForKey("id")
else newId = 1
} catch {
let fetchError = error as NSError
print(fetchError)
}
// Do the new insert afterwards
Upvotes: 3
Reputation: 861
I think you are sending a string value (781EFF10-A9F1-4710-98C1-6D342B2EB480) and core data is expecting an NSNumber (Int). Obviously, 781EFF10-A9F1-4710-98C1-6D342B2EB480 is not a number.
Core data always stores Int (Doubles, Float, etc...) values as NSNumber, for example:
let intValue
let intValueInNSNumber = NSNumber(int: intValue)
The difference is that intValue (Int) is a primitive type, while NSNumber is an object.
What's the type for the attribute "id"?
Because, if the attribute is of type "Int" you will have to change it to "String" and it should work.
Upvotes: 0