Core Data Object for ID Only Found Once - ios

I've got a huge xml File which needs to be parsed.
For different Tags inside the xml, e.g Football Soccer Data, I create NSManagedObjects e.g. SoccerPlayer and so forth.
I also need to use these objects a few times within the parsing method and so I created an Object which finds me the right object for the id I provide.
This works fine for the first game inside the xml but won't work for any one after that.
Could be the problem that I have to delete a few objects as I parse through the xml?
For my XML Parsing Framework, I use TouchXML.
Has anyone else experienced this behaviour before?

I agree with the comment that some code would help -- it's hard to understand exactly what the problem is. Nevertheless, I'll point out that the documentation for NSManagedObject's -objectID says:
Important: If the receiver has not yet been saved, the object ID is a
temporary value that will change when
the object is saved.
So, if you're creating an object, storing it's objectID, saving the context, and then trying to find the object with the objectID that you stored, you're probably going to fail because the temporary objectID was replaced with a permanent one when the context was saved.

Related

Can I specify a objectId when creating new PFObjects?

Swift / iOS
Can anyone tell me if it is possible to specify the PFObject objectId value when creating new objects?
I've obviously attempted but the save fails. (which might just be the answer)
The reason I am asking is I wondered if anyone had found a "trick" that would allow me to specify.
I am using PFObject.saveInBackground { method to persist the new object.
No you can not. Parse sets the objectId on the server during the save operation.
The reason your operation is failing is because Parse is looking for an object on the server with the id that you are specifying and is then trying to update that object but it cannot find the object.

NSKeyArchiver and NSKeyUnarchiver

I'm quite new to Swift, and I just started with persistence. I was wondering how the NSKeyUnarchiver works.
NSKeyedUnarchiver.unarchiveObject(withFile: file)
This is my current code. I have the file, but I don't know exactly what I'm getting. What if I archived multiple objects? How do I know which one I'm pulling? Somebody please help.
Only a single object can be archived per file. However, this can be an array, a dictionary, or other collection type, which stores multiple objects.

iOS - Appending element to list in realm does not persist element

I am adding a song to a List in my Playlist object with the following code:
func addSongsForPlaylist(songs: [Song], list: Playlist) {
try! realm!.write {
for song in songs {
list.RLMsongs.append(song)
}
}
}
Where songs is just an array of the songs that I want to add. The songs in songs are non persisted objects (not in realm yet), but list is already persisted in Realm.
I have found quite a few questions here on stackoverflow that seem to ask the same question but all their solutions were having to do with wrapping the append in a write transaction which I am already doing as you can see.
I have also tried the following:
try! realm!.write {
list.RLMsongs.appendContentsOf(songs)
}
What is happening is that if I enter po list.RLMsongs in the console the new song is there and it looks great, but if I enter po list its RLMsongs property is missing the new song. How can both be true? It seems to contradict itself and seems like there is something fundamental that I am missing about RealmSwift.
It looks like it is updating the list in memory but not actually committing to Realm. Therefore, I thought maybe the write block was not committing properly and wrapped it in a do catch but the catch is never run so the write transaction should be successfully committing.
EDIT:
Also, I noticed that I am able to remove the write transaction and it DOES NOT give me an error. I think this could be a clue as to what is going on here. Is it possible that the List is considered non persisted and therefore does not update properly in realm at all even though the contents of the list (the songs) are persisted objects?
That's because po list shows the contents of the instance variables of the Realm object, not the contents of the Realm. Realm doesn't duplicate all the contents of the database into the instance variables of the object instances because that would be quite wasteful.
Realm provides an LLDB plugin (rlm_lldb.py) that teaches the debugger to show actual Realm-backed contents rather than the unused instance variables. However, it only works with Objective-C stack frames due to limitations in the LLDB Python API for Swift language support.
Turns out that my issue was that I had to re-fetch the Playlist from realm...somehow the Playlist as it was passed into the function was not being considered a valid persisted object in realm. (Even though I have other update functions that work the same way that update other properties instead of appending objects to the song list and those update functions work fine)
My only guess is that something to do with appending to a list inside of a persisted object somehow works differently and the list must be explicitly fetched within the local scope and not just passed in as a function parameter. I could be wrong about this however. I just know this is how I got it to work on my end.

Can I do partial saves with NSKeyedArchiver?

I have a database object and some photos objects.
The database object contains an integer property and a mutable dictionary property.
The integer keeps track of the next free number to use as a mutable dictionary key when I create a new photo object and the mutable dictionary contains pointers to photo objects.
Photo objects contain an image, an image description and the date the image was taken.
I've been using NSKeyedUnarchiver and NSKeyedArchiver to read and write these objects in and out when my applicationDidBecomeActive and applicationWillResignActive methods trigger.
And, it's all been working well. When applicationWillResignActive triggers, it calls NSKeyedArchiver and points it to the database object as the root. The coder then writes out the integer and then when it encounters the mutable dictionary, it descends into it and each photo object is called to save its properties which are the image, the description and the date.
As I said, it's all been working well. But, it has seemed slower and slower as the number of photos has increased so I did some timings.
I found that reading the archive in is roughly 25 times faster than writing it out.
So, I conceived the idea of only writing out the photos which are new or changed as a method of speeding up the write side. After all, most of the photos are from past sessions and I might have 30 or 50 of them from before and I might only shoot two or three new ones this time.
I created some flags that indicate if a photo is new or old. When applicationWillResignActive triggers and I find myself down in the photos object handling each encodeWithCoder call, I save the image, description and date if the photo is new and I skip saving if it is old.
Well, I did not get the result I'd hoped for :-)
When applicationWillResignActive triggers, all the photos I skip writing out end up getting written out as empty photo objects which overwrites the previous photo objects out there with the same key. Then, when I load them back in, I've got bupkis, nada, zip.
First question, I guess, is can I write out only part of my object tree and have the parts I don't write out still remain out there intact from an earlier full write? I'm beginning to wonder if that might be a naive idea.
Gallymon
Using archives of some array of objects is going to be increasingly inefficient as the archive grows. This is exacerbated by the fact that your objects include images. Two thoughts:
You should consider using Core Data for storing this data. (You could use SQLite, directly, too, but Core Data is the preferred object persistence technology in iOS.) This way, when you want to save a new object, you just add that new object, and don't archive the whole collection of objects every time.
Furthermore, if speed is of primary interest and if your images are large, SQLite (the database that Core Data employs by default) is inefficient when handling large BLOBs (i.e. things like images). So, as inelegant as it sounds, you probably want to save images to your Documents folder, and only store a image file URL or path in CoreData.
why don't you save the image only on the init method ? if you create the object chances are you want to save it. so place the flag hasChanges == off in the init method and you check that flag for saving...

Best alternative for 'long term' storing model-view-controller data in Objective-C/ios

I am planning on creating my app in a 'Model-View-Controller'(MVC)-style, and in the end, for me at least, this means that all data is stored in the controller-class. Let's say I have a class Player, and the player has several objects of class Weapons or Equipment or whatever. The initialization of Controller* stores the player(s), so if I can store/save only the Controller-object over time, even if the app or the device restarts, that would be nice. I did this in Java one, I put in Serialization = 100L;(or something like it) in the top of the file of every object that would be included when saving the Controller-object, and it worked perfectly. Is this possible in ios/cocoa-touch/objective-c?
I have read and used Core Data (not very much), but that is just a database-table, sql?, which would have me extract every piece of information of every object?
For instance, if the object Player* has a member NSString *name;, I would have to save the actual string in Core Data, instead of saving the object of the player? Like, varchar.
If there is any way to store an entire custom object on the device for further use, I would very much like to know what it's called, and where I can read about it/tutorials.
Read up on the NSCoding protocol. You can make your object complient to it, then serialized it and save it to a file. Later you can restore it to the same state by using a decoder. For sure some other posts that cover this topic on SO.

Resources