NULL Objects in Received Playlists - cocoalibspotify-2.0

Since recently, among the fetched playlist objects is a NULL object is contained in the resulting array. It looks like a nasty bug, as in the debugger a memory address is given, but no object type could be resolved. It crashes within Cocoalibspotify while iterating the array.
Someone else experiencing that issue?

I found the issue:
Among Spotify's Top Tracks, there is the song "Love Is All I Got - Original Mix". It's album does have a nil cover. As I'm creating the array with covers via the following line, for this track's cover, an NSNull object is inserted, which makes cocoalibspotify crash.
NSArray *covers = [toptracks valueForKeyPath:#"album.cover"];

Related

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.

Cannot delete objects in other context

I am facing this problem consistently for over 3 months. I have searched a lot and read related docs and visited many forums but couldn't find working solution. I am getting typical NSManagedObject error while deleting objects. An NSManagedObjectContext cannot delete objects in other contexts.
I tried to go around and tried to delete object using its NSManagedObject ID but to no avail.
NSManagedObjectID *findingsSurveyDataItemApiId = [findingsSurveyDataItemApi objectID];
[self.managedObjectContext deleteObject:[self.managedObjectContext objectWithID:findingsSurveyDataItemApiId]];
Can anyone tell why is above solution still not working?
PS: I have two managed object context in the app.
I guess it might be a misleading error message from Core Data. If the object you want to delete has not yet been saved to the persistent store, objectWithID will not return a valid object, according to the docs:
The data in the persistent store represented by objectID is assumed to exist—if it does not, the returned object throws an exception when you access any property (that is, when the fault is fired).
Use existingObjectWithID:error: instead and check if it returns a non-nil object before trying to delete it.

CoreData fault - how to get data

I've researched tons of questions and documents about CoreData returning faults instead of actual values:
Relationship 'whiskers' fault on managed object (0xb7abab0)
This happens when I'm trying to get the count for the number of whiskers, such as:
self.numWhiskersLabel.text = [NSString stringWithFormat:#"%d", cat.whiskers.count];
Even if I try to log the whiskers set directly I still get a fault:
NSLog(#"whiskers: %#", cat.whiskers);
I understand that "Core data will not return full object until there is a need to access the actual value of that object. Each of your returned objects will be a 'fault' until this point." That's great, but there is a need to access the actual value at this point. I need the value right now! So how do I get out of this oxymoron? How can accessing the count of a Set not be considered needing the value?
I didn't get any feedback from my comment so I'm just going to assume whiskers is a set of NSManagedObjects
The set wont be loaded initially because internally it's coming from another table in the db. When you access .whiskers.count it still doesn't need to go and get the data yet, because all you're wanting is the number of whiskers in the set.
When you pull a whisker out of the set, then it will be faulted, try doing
NSLog(#"whiskers: %#", [cat.whiskers.anyObject anyProperty]);
That should give you a loaded NSManagedObject.
This is an error condition. Something is wrong with that NSManagedObject instance. Either it was deleted before you accessed it or you are trying to touch it from the wrong thread.
Please edit your question and show the code that is accessing that NSManagedObject.
Also, what happens when, in the debugger, you just do a po cat? Do you see the full Cat object or is that giving a fault error as well?

An MPMediaQuery for playlists (on iPod) includes some albums

I've instantiated a query to request a collection of all the playlists on my iPod Touch. The result, returned from the MPMediaQuery collections property, contains 43 items. These include all 17 of the PlayLists that the native Music app shows. However, the collection also contains 26 "playlists" that are actually albums from my iPod library. That represents some(but not all) of the albums on the iPod.
I've tried to see if there was an MPMediaPlaylist attribute that might distinguish the albums from actual playlists, to no avail. I looked at the sections of the collection to see if real playlists are kept in a separate sections from the albums, but there was only a single section. Finally, I looked to see if the albums have a PersistantID, which the documentation indicates is unique to playlists. All the items in the array have a PersistantID.
The Music app has no trouble displaying just the 17 actual playlists, so there must be something I'm missing. Here is the code used to build the query:
MPMediaQuery * myPlaylistsQuery = [ MPMediaQuery playlistsQuery ];
NSArray * playlists = [ myPlaylistsQuery collections ];
Here is a sample of the data that gets logged when the contents of the "playlists" array is interrogated:
=====================================================
List of playlists
.... There are 01 sections in the playlist collection
.... There are 43 MPMediaPlaylist objects in the playlist collection
Bach
.... Persistant ID: 17002820337772537981
Best of Simon and Garfunkel
.... Persistant ID: 2965021518813542622
Blue
.... Persistant ID: 11514004552991695558
Blues
.... Persistant ID: 14243796139384893728
.... (etc)
In the above listing, the entries "Bach", "Best of Simon and Garfunkel" and "Blue" represent albums. The entry "Blues" represents the first of the true playlists that I've defined on iTunes.
I suppose that I could compare the items returned from the playlist query against a the items in an albums query, and eliminate any matches. Is there a more straightforward solution?
I'm using [[MPMediaQuery playlistsQuery] collections] frequently and never have get an album returned as result. I guess that there is an issue somewhere else in your code. For example you still can customize the playlistsQuery after creating it with adding/removing parameters manually and if you change to much you could even let the query return albums instead of playlists.
Especially check the groupingType property of the query. For the playlistQuery it should be set to MPMediaGroupingPlaylist per default, but maybe you have overridden or removed this property manually for your query.
Otherwise there only remains the possibility of an bug in your devices system API or iTunes library. But this is very, very, very unlikely!

Strange CoreData error ... value returned from insertNewObjectForEntityForName: appears to be corrupt

I have a very strange error happening in an App that has been working for a long time.
I can no longer create one of my entities in my CoreData model.
When I create one particular entity in my model and try to print it using NSLog( #"%#", obj ), I get this strange message:
2011-11-08 13:03:05.936 iLearnFast[31541:15503] -[__NSCFNumber objectID]: unrecognized selector sent to instance 0xa069e20
When I loop over the attributes / relationships for this object and print them out, one particular one to one relationship returns a strange value from [obj valueForKey:]. The value it returns is the same pointer / object that is mentioned in the above error message.
I thought I might have been corrupting memory somewhere, but I inserted the code to create the entity at the very beginning of my executable as soon as datastructures are initialized, and I get the same problem. I am extremely confident that I have not made any memory errors at this point (and a memory error would be more random ... I can create thousands of objects, and always the same entity has the same problem with the same relationship, and no other entities ever have a problem).
After narrowing down the problem to this one relationship, I found that I could make the error go away by renaming the relationship to anything else. The relationship has been called "file" since my App was created.
I can make my code work again by renaming the property, although it messes up my automatic lightweight migration, but now I have to deal with figuring out how to do a more complicated migration.
If anyone has any ideas as to what might be going wrong, I would really appreciate it.
This is baffling me, and really feels like a bug in Apple's SDK.
I'm currently using XCode 4.2 and tried both the SDKs for both iOS5.0 and iOS4.3 and both had the same behaviour.
Ron
2011-11-08 13:03:05.936 iLearnFast[31541:15503] -[__NSCFNumber
objectID]: unrecognized selector sent to instance 0xa069e20
I guess you have a leak in your code. This line means that you trying to access objectID property which contains in your custom NSManagedObject, but for some reason that object no longer lives. Try to check your code on memory leaks.
I saw this same issue arise in a Swift project using Core Data. The issue only raised it's head when I pushed the app onto a device (it had been working fine in the simulator for some time).
The issue centred around a relationship between two entities. To illustrate see problem image:
After looking around SO for sometime I decided to rename the relationships, captain and player. See fix image:
Only after renaming both 'ends' of the relationship did the error go away.
I had same error message and in my case reason was that I had relation property teacher and created read-only property isTeacher.
This issue caused by Objective-C name conventions: CoreData was confused in getting teacher property. Instead of accessing real relation and giving me real object it taking isTeacher getter with BOOL type, cast it to NSNumber and try to deal with it like CoreData relation and call objectID.
After renaming isTeacher to isTeacherLicence problem gone.

Resources