An MPMediaQuery for playlists (on iPod) includes some albums - ios

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!

Related

How to retrieve videos from playlist from particular category

How to retrieve videos from a playlist from a particular category? Is that even possible to do?
I did try this call :
https://www.googleapis.com/youtube/v3/videos?part=snippet%2CcontentDetails%2Cstatistics&maxResults=50&myRating=like&chart=mostPopular&videoCategoryId=10
But no luck
You may use the Search: list method which returns a collection of search results that match the query parameters specified in the API request.
By default, a search result set identifies matching video, channel, and playlist resources, but you can also configure queries to only retrieve a specific type of resource.

Realm Many to Many Query (Inverse too!)

My app's db has a many to many relationship between a Feed object and a Tweet object. This is to keep track of which feeds every tweet belongs in. If you're familiar with Twitter, imagine the main feed, a list feed, a user profile feed, etc.
How can I make a query using an NSPredicate to get a list of Tweets that exist in a specific Feed (and, inversely, get a list of Feeds that a Tweet exists in)? It seems that queries on inverse relationships does not work in Realm, so what are my options?
If I understand your question correctly this part of the documentation should be helpful:
Inverse Relationships Links are unidirectional. So if a to-many
property Person.dogs links to a Dog instance and a to-one property
Dog.owner links to Person, these links are independent from one
another. Appending a Dog to a Person instance’s dogs property, doesn’t
automatically set the dog’s owner property to this Person. Because
manually synchronizing pairs of relationships is error prone, complex
and duplicates information, Realm exposes an API to retrieve backlinks
described below.
With inverse relationships, you can obtain all objects linking to a
given object through a specific property. For example, calling
Object().linkingObjects(_:forProperty:) on a Dog instance will return
all objects of the specified class linking to the calling instance
with the specified property.
I guess you can do something like:
//assuming your Tweet object has a property like "let feeds = List<Feed>()"
someTweet.linkingObjects(Feed.self, forProperty: "feeds") //should return feeds your Tweet is in
But still I don't think I understand your question clearly. From my point of view your first requirement:
get a list of Tweets that exist in a specific Feed
should have a straightforward solution such as having a property in your Feed object like:
let tweets = List<Tweet>()
I wish you can clarify your situation further.
I wonder if it's possible to simplify the model a bit so many-to-many isn't necessary.
My understanding of Twitter is that tweets aren't 'owned' by any feeds. They simply exist on the platform, and are referenced by any number of feeds, but don't actually belong to any specific feed.
So a model setup like this should be appropriate:
class Tweet : Object {
}
class Feed : Object {
let tweets = List<Tweet>()
}
You can do a reverse lookup on a Tweet to see if there are any feeds in which it is currently visible, and you can simply use the tweets property of Feed objects to see which tweets they're displaying
Since the linkingObjects reverse lookup method of Realm simply returns a standard Swift Array, if you did want to filter that further, you could just use the system APIs (like filter or map) to refine it further.
Otherwise, if you really do want to be able to use Realm's NSPredicate filtering system both ways, then, as messy as it is, you would need to manually have each model linking to a list of the other:
class Tweet : Object {
let feeds = List<Feed>()
}
class Feed : Object {
let tweets = List<Tweet>()
}
While it's not recommended (Since it adds additional work), it's not disallowed.
Good luck!

Fetch Core Data entity with a filtered set of child elements based on a property

I'm developing my first application with CoreData and I'm struggling with a common problem I think.
Let's say I have an entity Playlist which has a many to many relationship with another entity Song and also Video. So my Playlist object looks like this
class Playlist : NSManagedObject {
var songs: NSSet
var videos: NSSet
}
Song and Video entities both have a Boolean field "removed" that I use to track which song or video has been removed from the playlist. I later call my remote API to remove it on server's side but this is for offline purpose.
What I want is to retrieve from CoreData a Playlist object with its list of songs and videos that are not removed (so those with removed = false).
One solution I see would be to get all the elements by simply fetching on the Entity Playlist and then filter out manually but I'd like to know if I can do this more elegantly using Core Data.
Welcome to Core Data. The way this works is a follows:
First fetch the playlists. They have a to-many relationship with songs no matter if they are deleted of not. The removed property is not in the Playlist entity, so it does not matter when fetching playlists.
Then get the filtered attribute set by applying a predicate:
let validSongs = aPlaylist.songs.filteredSetUsingPredicate(
NSPredicate(format: "removed = false")
)
In other words, you do not have to worry about which songs exactly Core Data is retrieving with your playlist. There are a lot of optimizations under the hood, so most likely Core Data will be using a mechanism called "faulting" to just retrieve the data it needs. There is noting else for you to do!
IMO, this is also the most "elegant" solution. To make it even more concise, you can add a method to your Playlist entity that retrieves the valid songs.
func validSongs() -> NSSet {
if !self.songs.count { return NSSet() }
return self.songs.filteredSetUsingPredicate(
NSPredicate(format: "removed = false")
)
}
And then access the valid songs with
aPlaylist.validSongs

videoChartNotFound error for some video categories

API calls https://www.googleapis.com/youtube/v3/videoCategories?part=snippet&regionCode=US&key=API_KEY can retrieve a list of available videoCategory for certain country.
For example, videoCategory id 43:
However, when i retrieve video by this videoCategory id 43, for example https://www.googleapis.com/youtube/v3/videos?part=snippet%2C+contentDetails&chart=mostPopular&regionCode=MY&videoCategoryId=43&key=API_KEY, i get error instead:
At the first glance, i thought it was due to assignable is false, but it's not the case, because some videoCategoryId which was assignable=false can retrieve videos too.
videoCategoryId id 30, assignable is false:
videoCategoryId 30 have no problem to get videos:
Search API is ok(some categories return only ~2 videos), for example this API calls, https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&maxResults=20&order=relevance&videoCategoryId=43&type=video&key=API_KEY:
I'm not sure it's bug or not. Because it's possible videoCategory id 43 is not under mostPopular chart and lead to this error. But how is it possible to detect and filter it out on videoCategories resource API? there's no flag to indicate this category cannot work with video resource API.
I ran into this as well, and it seems that the bug is that "Movies" and "Trailers" should be set as assignable. Per this, https://developers.google.com/youtube/v3/docs/videoCategories, if a category is assignable it has videos associated with it. So it makes sense that retrieving videos for non-assignable categories would fail, but it does not make sense that those two non-assignable categories do, in fact, have associated videos (although "Trailers" only returns one result, which is strange).
I suppose a temporary workaround is to just include assignable categories, and manually include movies and trailers.

One query for two core data relationships?

I have the following data model:
And I'd like to have a property on the playlist object that points to its list of songs. Right now I have something like:
self.songs = [self.playlistMemberships valueForKey:#"song"];
But I'm noticing that this is very slow and core data seems to be firing off faults for each individual song. Any thoughts on how to make a single call to pull all the song info? Thanks!
PlaylistMembership just seems to get in the way -- can you relate Playlist to Song directly and cut out the PlaylistMembership? I think that'd let Core Data fetch all the songs at once rather than fetching all the memberships and then having to go back to get each song.
If you can't or prefer not to get rid of the membership entity, use setRelationshipKeyPathsForPrefetching: to specify that song should be fetched along with the membership.

Resources