How to retrieve spotify playlist in iphone application - spotify

I have downloaded IOS Cocoa library of Spotify, which have sample project for playing songs in spotify.
I need to fetch the playlist of a Spotify particular user in an iPhone application??

You can try this -
[SPAsyncLoading waitUntilLoaded:[SPSession sharedSession] timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedession, NSArray *notLoadedSession)
{
// The session is logged in and loaded — now wait for the userPlaylists to load.
[SPAsyncLoading waitUntilLoaded:[SPSession sharedSession].userPlaylists timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedContainers, NSArray *notLoadedContainers)
{
// User playlists are loaded — wait for playlists to load their metadata.
NSMutableArray *playlists = [NSMutableArray array];
[playlists addObject:[SPSession sharedSession].starredPlaylist];
[playlists addObject:[SPSession sharedSession].inboxPlaylist];
[playlists addObjectsFromArray:[SPSession sharedSession].userPlaylists.flattenedPlaylists];
[SPAsyncLoading waitUntilLoaded:playlists timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedPlaylists, NSArray *notLoadedPlaylists)
{
// All of our playlists have loaded their metadata — wait for all tracks to load their metadata.
arrPlaylist = [[NSMutableArray alloc] initWithArray:loadedPlaylists];
NSLog(#"arrPlaylist %#",arrPlaylist);
}];
}];
}];

Related

Playlist loaded property is YES but playlist.items have null items inside

I'm using the following code to load a playlist
-(void)loadPlaylist:(NSString *)playlistURI withCompletionBlock:(spotifycompletionWithData)completionBlock andfailed:(failedBlock)failedBlock {
NSURL *playlistURL = [NSURL URLWithString:playlistURI];
[[SPSession sharedSession] playlistForURL:playlistURL callback:^(SPPlaylist *playlist) {
[SPAsyncLoading waitUntilLoaded:playlist timeout:kSPAsyncLoadingDefaultTimeout+10 then:^(NSArray *loadedItems, NSArray *notLoadedItems) {
if(notLoadedItems.count >= 1){
[SVProgressHUD dismiss];
failedBlock();
return;
}
self.playlist = [loadedItems lastObject];
}];
}];
}
I'm observing the playlist.loaded property and I see its YES
but when I'm looking into the playlist.items lots of them are null.
What can I do?
The playlist.loaded == YES just means that the playlist's own metadata is loaded - the name, owner, number of items etc. The items themselves load separately, so you need to separately use SPAsyncLoading to load them.
Note that loading the entire contents of a playlist at once is a pretty bad idea - playlists get huge, and if you try to load 10,000 items at once things are going to get bad fast on an iOS device.
Instead, you should consider loading the items in chunks as the user scrolls around your UI.

Saving video files to iCloud

I am currently trying to save video files to iCloud. I am using Core Data to save filename strings (filename.MOV) for each video, to then retrieve them from the ubiquity container. It all works locally (files save, and can be accessed from their URLs), but I am struggling to obtain the videos over iCloud. The Core Data syncs, so I have access to the file names, but when I try to obtain the video from the URL, I am unable to.
This is how I save the video after obtaining its url (videoURL below) from UIImagePicker, and creating a unique string from the current date:
NSString *videoFileName = [stringFromDate stringByAppendingPathExtension:#"MOV"];
NSURL *ubiquityContainer = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
NSURL *saveToURL = [ubiquityContainer URLByAppendingPathComponent:videoFileName];
BOOL ok;
ok = [[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:videoURL destinationURL:saveToURL error:nil];
if (!ok) NSLog(#"error saving");
I then have a Core Data table view to list all of the videos. Here I observe changes in the Core Data to sync with iCloud and reload (this all still works fine):
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reloadFetchedResults:)
name:#"SomethingChanged"
object:[[UIApplication sharedApplication] delegate]];
}
- (void)reloadFetchedResults:(NSNotification*)note {
[self performFetch];
}
At this point, I want the ubiquity container to update, so that when I choose a video, and segue to a view controller to watch it, the video file can be found. (self.video is my Core Data video entity) (asset is is the video asset, which I can play back)
NSURL *ubiquityContainer = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
ubiquityContainer = [ubiquityContainer URLByAppendingPathComponent:self.video.url];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:ubiquityContainer options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]];
AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
This is where I run in to trouble. On the device where I took the video it works, but on another device, no file is found (objectAtIndex:0 is beyond bounds).
This is the metadata query I call at view did load:
NSMetadataQuery * query = [[NSMetadataQuery alloc] init];
NSString * filePattern = [NSString stringWithFormat:#"%#", self.video.url];
[query setPredicate:[NSPredicate predicateWithFormat:#"%K LIKE %#",
NSMetadataItemFSNameKey, filePattern]];
[query startQuery];
My metadata query may be at fault, or there may be more issues. Any help would be greatly appreciated!
I assume you are on iOS, which means on your second device the media file hasn't been downloaded (iOS doesn't download iCloud files until you actually access them, OS X downloads everything - see the docs).
To ensure the file is on the device use startDownloadingUbiquitousItemAtURL:error: or coordinateReadingItemAtURL:options:error:byAccessor: if you want to know when it's done (in the Accessor block). You will need to call the later anyway to do your coordinated read, so the first method has limited usefulness.

Hard CoreData + iCloud scenario

i'm having a very hard issue to solve. I've got this scenario:
My app uses CoreData to storing objects, I want to implement iCloud sync between devices... and my app requires an initial populated database.
The first time I launch my app, it's going to populate my database on the cloud and marks to YES some db'fields as "databaseInstalled". These fields are synced in the cloud too.
Now when another device launch the app for the first time, I was hoping to retrieve the field "databaseInstalled" to check whether inject or not some data but it's wrong...
If databaseInstalled is false, we inject data, if databaseInstalled it's true, we wait for iCloud sync.
The problem is that I retrieve the persistentStoreCoordinator asynchronically because of I don't want to block the app that is waiting to download data from iCloud...
So how can I know a priori if i need to populate the database or it has been filled on another device and I've just to download from iCloud the populated one?
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if((__persistentStoreCoordinator != nil)) {
return __persistentStoreCoordinator;
}
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSPersistentStoreCoordinator *psc = __persistentStoreCoordinator;
// Set up iCloud in another thread:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// ** Note: if you adapt this code for your own use, you MUST change this variable:
NSString *iCloudEnabledAppID = #"this is a secret!";
// ** Note: if you adapt this code for your own use, you should change this variable:
NSString *dataFileName = #"you do not have to know.sqlite";
// ** Note: For basic usage you shouldn't need to change anything else
NSString *iCloudDataDirectoryName = #"Data.nosync";
NSString *iCloudLogsDirectoryName = #"Logs";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
if (iCloud) {
NSLog(#"iCloud is working");
NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
NSLog(#"iCloudEnabledAppID = %#",iCloudEnabledAppID);
NSLog(#"dataFileName = %#", dataFileName);
NSLog(#"iCloudDataDirectoryName = %#", iCloudDataDirectoryName);
NSLog(#"iCloudLogsDirectoryName = %#", iCloudLogsDirectoryName);
NSLog(#"iCloud = %#", iCloud);
NSLog(#"iCloudLogsPath = %#", iCloudLogsPath);
// da rimuovere
//[fileManager removeItemAtURL:iCloudLogsPath error:nil];
#warning to remove
if([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
NSError *fileSystemError;
[fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]
withIntermediateDirectories:YES
attributes:nil
error:&fileSystemError];
if(fileSystemError != nil) {
NSLog(#"Error creating database directory %#", fileSystemError);
}
}
NSString *iCloudData = [[[iCloud path]
stringByAppendingPathComponent:iCloudDataDirectoryName]
stringByAppendingPathComponent:dataFileName];
//[fileManager removeItemAtPath:iCloudData error:nil];
#warning to remove
NSLog(#"iCloudData = %#", iCloudData);
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudLogsPath forKey:NSPersistentStoreUbiquitousContentURLKey];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:nil];
[psc unlock];
}
else {
NSLog(#"iCloud is NOT working - using a local store");
NSLog(#"Local store: %#", localStore.path);
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:localStore
options:options
error:nil];
[psc unlock];
}
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"iCloud routine completed.");
Setup *install = [[Setup alloc] init];
if([install shouldMigrate]) {
HUD = [[MBProgressHUD alloc] initWithView:self.window.rootViewController.view];
HUD.delegate = self;
HUD.labelText = NSLocalizedString(#"Sincronizzazione del database", nil);
[self.window.rootViewController.view addSubview:HUD];
[HUD showWhileExecuting:#selector(installDatabase) onTarget:install withObject:nil animated:YES];
}
else {
[[NSNotificationCenter defaultCenter] postNotificationName:#"setupCompleted" object:self];
}
//[[NSNotificationCenter defaultCenter] postNotificationName:#"icloudCompleted" object:self userInfo:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"setupCompleted" object:self];
});
});
return __persistentStoreCoordinator;
}
You can't know whether or not there's going to be data available in iCloud until you finish syncing with iCloud. That means that you've got two options:
Make the user wait until the sync is done.
Start up with your default database and merge changes from iCloud when possible.
With iCloud, you need some strategy for resolving conflicts between local data and cloud data because you have to deal with the fact that users might change data on more than one device at the same time. Once you have that in place, it seems pretty clear that the second option above is the better one: users get to start using your app right away, and data from the cloud is merged when it's available.
I had exactly same problem.
Check out my question & my answer to it iCloud + CoreData - how to avoid pre-filled data duplication?
Actually it doesn't work 100% ok. If you dare to try it I can explain you how you might make it work 100% correctly (I haven't tried yet, though).
Taking into account that you have a lot of data to pre-populate my solution might now work out for you.
There is no way to determine whether a data store is being opened for the first time. At least not on iCloud Core Data store. Think of it, iCloud should also work off-line – that is, all changes should be buffered when the user is disconnected from the Internet and then uploaded when the connection is restored. There is no way to check whether a data store was initialized without potentially making the user wait for a few minutes (or even indefinitely if the device is off-line) to ask iCloud's copy of the data sore.
To solve this, you'll need to follow these four simple guidelines:
Have a way to de-duplicate pre-populated records.
Have a way to identify pre-populated records and differentiate it from user-entered ones.
Run the de-duplication process every time new transaction records came in from iCloud.
Only seed data records once per device/account combination.
You can read more details here: http://cutecoder.org/programming/seeding-icloud-core-data/

facebook sdk question regarding dialog feed iphone

I use this code to post in facebook from my app in iphone
NSString *title=[NSString stringWithFormat:#"Posted from Poems of Love v2 iPhone/iPod/iPad touch app - { Poem Name: "];
//& titletext.text & ""\",";
NSString *alltitle= [title stringByAppendingString:poemtitle.text];
alltitle= [alltitle stringByAppendingString:#" } - { Author:"];
alltitle= [alltitle stringByAppendingString:authorname.text];
NSString *alltitle1= [alltitle stringByAppendingString:#" }"];
NSString *list = poembody.text;
NSString *kAppId=#"numid";
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
kAppId, #"app_id",
#"http://www.poemsofloveapp.com", #"link",
#"http://3.bp.blogspot.com/_co4MVQE_2l0/TPRh6TBjaZI/AAAAAAAAAOg/E0kgWLd4ieE/s1600/poemsoflovev2logo.png", #"picture",
alltitle1, #"name",
#"\nhttp://www.poemsofloveapp.com - Join us on facebook!\n", #"caption",
list, #"description",
#"",#"message",
nil];
[mainDelegate._session dialog:#"feed" andParams:params andDelegate:self];
The dialog shows up i tap skip or publish and then a second dialog shows up which is empty! no message on it nothing
Why is this happening?
My mistake sorry guys i called [mainDelegate._session dialog:#"feed" andParams:params andDelegate:self];
two times previously stupid i know!!!

Setting up basic relationship with Fetch Requests

I am wanting to set up a basic relationship with two entities in Core Data, but the relationship is either not saving, or is not working properly and I'm not sure why.
The two entities are Character and Avatar, its a one-to-one relationship. A character can have 1 avatar. Technically, it should be a "one avatar can be owned by many characters", but I'll deal with that later.
I want to add characters and assign them an avatar.
There are already 10 avatars in Core Data and 1 character, both of which I've verified via the Terminal and SQLite.
The problem is, I'm having troubling "finding an avatar by a name and then saving the relationship to a character".
So far,
I set up a fetch request called: "frqAvatarWithName" where the Predicate has the following structure:
[quote]
name == $AVATAR_NAME
[/quote]
This is so: I can find an avatar with a certain name; and then I can create a relationship with a character.
Issue 1: It gets to execute the query but then never displays how many records there are.
I get a EXC_BAD_ACCESS error in debug mode and I have traced it back to the fetch request template handling -- so, this must be in error or I have done it wrong.
Issue 2: I am not sure if I am even setting up this "basic" relationship up properly.
[code]
// This code is meant to find an avatar with a certain name and then save the relationship
// between a character and said avatar.
// This is my app delegate file for the moment
// All the files are present, and I have deleted/recreated the app various times
-(void)characterMaker
{
NSLog(#"Inside characterMaker...");
NSError *error = nil;
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObjectModel *model = [self managedObjectModel];
// Find an avatar with a specific name
NSString *nameToFind = #"avt_player_1";
// Use a Fetch request template
NSDictionary *subs = [NSDictionary dictionaryWithObjectsAndKeys:nameToFind, #"AVATAR_NAME", nil];
NSFetchRequest *fetchRequest = [model fetchRequestFromTemplateWithName:#"frqAvatarWithName"
substitutionVariables:subs];
// Set the entity to use
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Avatar"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
// Execute the query (it never even reaches this point)
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// Handle the error
NSLog(#"Error -- %#", [error localizedDescription]);
abort();
}
NSLog(#"Found %# records", [fetchedObjects count]);
// Print out avatar names
for (Avatar *a in fetchedObjects)
{
NSLog(#"Name = %#", [a valueForKey:#"name"]);
}
// This is where I would use `a` and store it in a character entity, and thus create the relationship
[/code]
I gave up on this and did the whole project with the FMDatabase project and SQLite; I've been able to resolve the problem this way.
Thread closed.

Resources