Getting Youtube Channel Playlist using Objective-C API - iphone

I'm trying to use Google's Objective-C Youtube APIs to fetch a youtube channel's playlist - with no luck.
-I downloaded Google's official API from:
http://code.google.com/p/gdata-objectivec-client/source/browse/#svn%2Ftrunk%2FExamples%2FYouTubeSample
But the sample App doesn't really do anything - its not even an iOS sample App. Seems to be a Mac OS App. Its Read-Me file says: "This sample should automatically build and copy over the GTL.framework as part of the build-and-run process."
Ok... and then what?
How do you get this to work in an iPhone App?
I haven't found any actual instructions to make this work.
Any idea what we're supposed to do here?

you can try source code at this path
https://bitbucket.org/eivvanov/youtubedemo/overview

I have spent a day and a half trying to figure it out on how to use the MAC OSX app they have given as an example. I ended up with an iPhone app which I manage to build to get all the Uploaded video I have from YouTube.
Link: YouTubeProject
In order to make it work:
You have to add the GData project from google
In the LTMasterViewController.m-> (GDataServiceGoogleYouTube *)youTubeService: put your username and password

The "gdata-objectivec-client" for youtube been superseded by a JSON-API Link. Scroll down to youtube.
For supporting the JSON-API here is the details Link.
And for fetching the playlist have a look at the Link.

For total newbies who are lost : consider a sample function that will help understand the entire cycle of fetch,parse,display etc and bring youtube channel's videos to your tableview specifically. im not writing the tableview part here
-(void)initiateRequestToYoutubeApiAndGetChannelInfo
{
NSString * urlYouCanUseAsSample = #"https://www.googleapis.com/youtube/v3/search?key={YOUR_API_KEY_WITHOUT_CURLY_BRACES}&channelId={CHANNEL_ID_YOU_CAN_GET_FROM_ADDRESS_BAR_WITHOUT_CURLY_BRACES}&part=snippet,id&order=date&maxResults=20";
NSURL *url = [[NSURL alloc] initWithString: urlYouCanUseAsSample];
// Create your request
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// Send the request asynchronously remember to reload tableview on global thread
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// Callback, parse the data and check for errors
if (data && !connectionError) {
NSError *jsonError;
NSDictionary *jsonResult = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError];
if (!jsonError) {
// better put a breakpoint here to see what is the result and how it is brought to you. Channel id name etc info should be there
NSLog(#"%#",jsonResult);
/// separating "items" dictionary and making array
//
id keyValuePairDict = jsonResult;
NSMutableArray * itemList = keyValuePairDict[#"items"];
for (int i = 0; i< itemList.count; i++) {
/// separating VIDEO ID dictionary from items dictionary and string video id
id v_id0 = itemList[i];
NSDictionary * vid_id = v_id0[#"id"];
id v_id = vid_id;
NSString * video_ID = v_id[#"videoId"];
//you can fill your local array for video ids at this point
// [video_IDS addObject:video_ID];
/// separating snippet dictionary from itemlist array
id snippet = itemList[i];
NSDictionary * snip = snippet[#"snippet"];
/// separating TITLE and DESCRIPTION from snippet dictionary
id title = snip;
NSString * title_For_Video = title[#"title"];
NSString * desc_For_Video = title[#"description"];
//you can fill your local array for titles & desc at this point
// [video_titles addObject:title_For_Video];
// [video_description addObject:desc_For_Video];
/// separating thumbnail dictionary from snippet dictionary
id tnail = snip;
NSDictionary * thumbnail_ = tnail[#"thumbnails"];
/// separating highresolution url dictionary from thumbnail dictionary
id highRes = thumbnail_;
NSDictionary * high_res = highRes[#"high"];
/// separating HIGH RES THUMBNAIL IMG URL from high res dictionary
id url_for_tnail = high_res;
NSString * thumbnail_url = url_for_tnail[#"url"];
//you can fill your local array for titles & desc at this point
[video_thumbnail_url addObject:thumbnail_url];
}
// reload your tableview on main thread
//[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
performSelectorOnMainThread:#selector(reloadInputViews) withObject:nil waitUntilDone:NO];
// you can log all local arrays for convenience
// NSLog(#"%#",video_IDS);
// NSLog(#"%#",video_titles);
// NSLog(#"%#",video_description);
// NSLog(#"%#",video_thumbnail_url);
}
else
{
NSLog(#"an error occurred");
}
}
}];
}

Related

Share Extension: Grab thumbnail in custom view controller like SLComposeServiceViewController

I'm trying to grab thumbnail image from a website so I can paste it on my custom UIViewController for share extension. I know SLComposeServiceViewController does this for free, but I have to make a customized view controller.
Is there any way to do this with existing APIs?
Thanks.
I also hit the limit in customizing SLComposeServiceViewController and had to create own preview.
Basic approach is like this:
for (NSExtensionItem *item in self.extensionContext.inputItems)
{
for (NSItemProvider *itemProvider in item.attachments)
{
//kUTTypeVCard, kUTTypeURL, kUTTypeImage, kUTTypeQuickTimeMovie
NSString *typeIdentifier = (__bridge NSString *)kUTTypeImage;
if ([itemProvider hasItemConformingToTypeIdentifier:typeIdentifier])
{
[itemProvider loadPreviewImageWithOptions:nil completionHandler:^(UIImage *image, NSError *error)
{
if (image)
{
//Use image
}
}];
}
}
}
Please note that
- (void)loadPreviewImageWithOptions:(NSDictionary *)options completionHandler:(NSItemProviderCompletionHandler)completionHandler
Loads the preview image for this item by either calling the supplied preview block or falling back to a QuickLook-based handler. This method, like loadItemForTypeIdentifier:options:completionHandler:, supports implicit type coercion for the item parameter of the completion block. Allowed value classes are: NSData, NSURL, UIImage/NSImage.
Try this code, to get a thumbnail from file URL:
NSURL *path = self.url;
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kQLThumbnailOptionIconModeKey];
CGImageRef ref = QLThumbnailImageCreate(kCFAllocatorDefault, (__bridge CFURLRef)path, CGSizeMake(600, 800 /* Or whatever size you want */), (__bridge CFDictionaryRef)options);
NSImage *thunbnail = [[NSImage alloc]initWithCGImage:ref size:NSZeroSize];

displaying JSON data with the help of dictionaries and array

I get the following error
[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x75a8e20
2013-04-20 08:56:14.90 MyApp[407:c07] *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]:
unrecognized selector sent to instance 0x75a8e20'
This is my first hands on working with JSON. I get the above mentioned error when I try to run the first piece of code where URL is a flickr url. When I use the photos as key it print the array and app abruptly quits.
#define flickrPhotoURL [NSURL URLWithString: #"http://api.flickr.com/services/rest/?format=json&sort=random&method=flickr.photos.search&tags=rocket&tag_mode=all&api_key=12345&nojsoncallback=1"]
- (void)viewDidLoad
{
[super viewDidLoad];
//this line of code will be executed in the background to download the contents of the flickr URL
dispatch_async(flickrBgQueue, ^{
NSData* flickrData = [NSData dataWithContentsOfURL:flickrPhotoURL]; //NOTE: synchronous method...But we actually need to implement asynchronous method
[self performSelectorOnMainThread:#selector(appFetchedData:) withObject:flickrData waitUntilDone:YES]; //when data is available "appFetchedData" method will be called
});
}
- (void)appFetchedData: (NSData *)responseData
{
//parsing JSON data
NSError *error_parsing;
NSDictionary *flickr_json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error_parsing];
NSArray* photo_information = [flickr_json objectForKey:#"photos"];
NSLog(#"Photo Information: %#",photo_information);
NSDictionary* photo = (NSDictionary*)[photo_information objectAtIndex:0];
humanReadable.text = [NSString stringWithFormat:#"Owner is %#",[photo objectForKey:#"Owner"]];
}
However when I run the same piece of code by replacing the key "photos" with "loans" and use the following URL and code
#define flickrPhotoURL [NSURL URLWithString: #"http://api.kivaws.org/v1/loans/search.json?status=fundraising"]
- (void)appFetchedData: (NSData *)responseData
{
//parsing JSON data
NSError *error_parsing;
NSDictionary *flickr_json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error_parsing];
NSArray* photo_information = [flickr_json objectForKey:#"loans"];
NSLog(#"Photo Information: %#",photo_information);
NSDictionary* photo = (NSDictionary*)[photo_information objectAtIndex:0];
humanReadable.text = [NSString stringWithFormat:#"loan amount is %#",[photo objectForKey:#"loan_amount"]];
}
, the app sets the correct information on the humanredable.text property. Am I using the wrong key for the first JSON ?
Firstly, thanks for publishing your Flickr API key as-is! It will be super useful for me to perform identity theft some day.
Second, another big thanks for not having read the data you got back. It starts like this:
{"photos":{"page":1, "pages":1792, "perpage":100,
^^^^^^^^^^
So the object for the key photos is a dictionary, not an array, thus,
NSArray* photo_information = [flickr_json objectForKey:#"photos"];
is wrong. Did you mean this instead:
NSArray* photo_information = [[flickr_json objectForKey:#"photos"]
objectForKey:#"photo"];
? Also, below when you construct the human readable description,
[photo objectForKey:#"Owner"]
is wrong, it should be
[photo objectForKey:#"owner"]
instead.

Opening iTunes Store to specific song

Ok, I have seen similar questions here but none are actually answering the problem for me.
I have a streaming audio app and the stream source returns to me the song title and artist name. I have an iTunes button in the app, and want to open the iTunes STORE (search) to that exact song, or at least close. I have tried the following:
NSString *baseString = #"itms://phobos.apple.com/WebObjects/MZSearch.woa/wa/advancedSearchResults?songTerm=";
NSString *str1 = [self.songTitle2 stringByReplacingOccurrencesOfString:#" " withString:#"+"];
NSString *str2 = [self.artist2 stringByReplacingOccurrencesOfString:#" " withString:#"+"];
NSString *str = [NSString stringWithFormat:#"%#%#&artistTerm=%#", baseString, str1, str2];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString:str]];
This call does indeed switch me to the iTunes STORE as expected, but then it pops up an error "Cannot connect to iTunes Store". I am obviously on-line as the song is actively streaming, and I am in the store. The search box in iTunes app only shows the song name and nothing else.
Here is an example of a generated string:
itms://phobos.apple.com/WebObjects/MZSearch.woa/wa/advancedSearchResults?artistTerm=Veruca+Salt&artistTerm=Volcano+Girls
I have tired taking the string it generates and pasting it into Safari, and it works OK on my Mac, opening to albums from the artist in the store. Why not on the phone?
Also, it seems to ignore both items, as it does not take me to the song by that artist. Does this require also knowing the album name (which I do not have at this time.)
Help would be appreciated. Thanks.
Yes, I am answering my own question.
After much digging and a talk with one of the best programmers I know, we have a solution, so I thought I would share it here. This solution takes the song name and artist, actually does make a call to the Link Maker API, gets back an XML document, and extracts the necessary info to create a link to the iTunes Store, opening the store to the song in an album by that artist that contains the song.
In the interface of the view controller, add:
#property (strong, readonly, nonatomic) NSOperationQueue* operationQueue;
#property (nonatomic) BOOL searching;
In the implementation:
#synthesize operationQueue = _operationQueue;
#synthesize searching = _searching;
Here are the methods and code that will do this for you:
// start an operation Queue if not started
-(NSOperationQueue*)operationQueue
{
if(_operationQueue == nil) {
_operationQueue = [NSOperationQueue new];
}
return _operationQueue;
}
// change searching state, and modify button and wait indicator (if you wish)
- (void)setSearching:(BOOL)searching
{
// this changes the view of the search button to a wait indicator while the search is perfomed
// In this case
_searching = searching;
dispatch_async(dispatch_get_main_queue(), ^{
if(searching) {
self.searchButton.enabled = NO;
[self.searchButton setTitle:#"" forState:UIControlStateNormal];
[self.activityIndicator startAnimating];
} else {
self.searchButton.enabled = YES;
[self.searchButton setTitle:#"Search" forState:UIControlStateNormal];
[self.activityIndicator stopAnimating];
}
});
}
// based on info from the iTunes affiliates docs
// http://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html
// this assume a search button to start the search.
- (IBAction)searchButtonTapped:(id)sender {
NSString* artistTerm = self.artistField.text; //the artist text.
NSString* songTerm = self.songField.text; //the song text
// they both need to be non-zero for this to work right.
if(artistTerm.length > 0 && songTerm.length > 0) {
// this creates the base of the Link Maker url call.
NSString* baseURLString = #"https://itunes.apple.com/search";
NSString* searchTerm = [NSString stringWithFormat:#"%# %#", artistTerm, songTerm];
NSString* searchUrlString = [NSString stringWithFormat:#"%#?media=music&entity=song&term=%#&artistTerm=%#&songTerm=%#", baseURLString, searchTerm, artistTerm, songTerm];
// must change spaces to +
searchUrlString = [searchUrlString stringByReplacingOccurrencesOfString:#" " withString:#"+"];
//make it a URL
searchUrlString = [searchUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL* searchUrl = [NSURL URLWithString:searchUrlString];
NSLog(#"searchUrl: %#", searchUrl);
// start the Link Maker search
NSURLRequest* request = [NSURLRequest requestWithURL:searchUrl];
self.searching = YES;
[NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue completionHandler:^(NSURLResponse* response, NSData* data, NSError* error) {
// we got an answer, now find the data.
self.searching = NO;
if(error != nil) {
NSLog(#"Error: %#", error);
} else {
NSError* jsonError = nil;
NSDictionary* dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
if(jsonError != nil) {
// do something with the error here
NSLog(#"JSON Error: %#", jsonError);
} else {
NSArray* resultsArray = dict[#"results"];
// it is possible to get no results. Handle that here
if(resultsArray.count == 0) {
NSLog(#"No results returned.");
} else {
// extract the needed info to pass to the iTunes store search
NSDictionary* trackDict = resultsArray[0];
NSString* trackViewUrlString = trackDict[#"trackViewUrl"];
if(trackViewUrlString.length == 0) {
NSLog(#"No trackViewUrl");
} else {
NSURL* trackViewUrl = [NSURL URLWithString:trackViewUrlString];
NSLog(#"trackViewURL:%#", trackViewUrl);
// dispatch the call to switch to the iTunes store with the proper search url
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] openURL:trackViewUrl];
});
}
}
}
}
}];
}
}
The XML file that comes back has a LOT of other good info you could extract here as well, including three sizes of album art, album name, cost, etc, etc.
I hope this helps someone else out. This stumped me for quite some time, and I thank a good friend of mine for making this work.
You are in fact using a URL for the search. That's why iTunes opens on search. My iTunes in Mac OS X also opens in search.
Use the Search API for iTunes to search for the content you want and get the artist, album or song ids so you can generate a direct URL for that content.
Look in the iTunes Link Maker how to create a URL for an artist or for a specific album and compose that URL on your app.
It appears that now iOS already opens the iTunes app directly when you try to open a itunes html url.
Example, trying to do a openURL on https://itunes.apple.com/br/album/falando-de-amor/id985523754 already opens the iTunes app instead of the website.

how to get objects from a json array in iphone?

I am working on an iPhone app which involves using json-framework.I am getting array using NSURL
[{"firstName":"X","lastName":"Y","id":1},{"firstName":"A","lastName":"B","id":2}]
How can i get these 2 objects as like if i query for id=1, the O/P is
id=1
firstName:X
lastName:Y
and putting it in a table.
I am googling the stuff from many days but didn't get any solution.
Please help me out , explanation through code is appreciated.
Thank You.
If your target SDK is ios4 or higher, you can use this project
https://github.com/stig/json-framework/
Once you add the source to your project, just
#import "SBJson.h"
and convert your Json string as follows
jsonResponse = [string JSONValue];
The method will fail if you don't have the full Json array in your string, but you can keep appending strings until it doesn't fail
To follow up for codejunkie's request below
you can assume in your data structure that the jsonResponse is an NSArray
In other implementations take care to test the response for NSArray or NSDictionary
NSArray * myPeople = [string JSONValue];
NSMutableDictionary * organizedData = [[NSMutableDictionary alloc] init];
for (NSDictionary * p in myPeople) {
[organizedData setValue:p forKey:[p valueForKey:#"id"]];
}
// now you can query for an id like so
// [organizedData valueForKey:#"1"]; and your output will be what you wanted from the original question
// just don't forget to release organizedData when you are done with it
https://github.com/johnezang/JSONKit
I use this to get data from a webservice that spits out 50 records each having another 20 internal elements similar to the one you specify...
I use the JSONKit in the following manner..(Had a look at SBJson a lot of user but i got confused from the word go.)
JSONDecoder *jArray = [[JSONDecoder alloc]init];
NSMutableArray *theObject = [[NSMutableArray alloc] init];
theObject = [jArray objectWithData:theResponseData];//objectWithString:theResponseString
NSMutableArray *csArray = [[NSMutableArray array] retain] ;
for(id key in theObject)
{
if([key valueForKey:#"firstName"] != Nil)
{
........
}
if([key valueForKey:#"lastName"] != Nil)
{
........
}
}
check it out and let me know if it works or not.. By the way Great responses guys... Good

How to get the bigger profile picture of a facebook page

I am getting an image from facebook by the URL: http://external.ak.fbcdn.net/safe_image.php?d=d282e1e7c86c9270232f97ddc737df39&w=90&h=90&url=http%3A%2F%2Fi52.tinypic.com%2F2q0ixzl.jpg
Now, I want a bigger version, like 200 by 200. Is there a URL for that? If not, how can I convert this image to a larger size?
Generally if you want to collect the profile pic of a user or page, the format for the icon size picture is:
http://graph.facebook.com/[page id/profile id]/picture
and for the large picture:
http://graph.facebook.com/[page id/profile id]/picture?type=large
EDIT Points to note:
If the image stored on the facebook servers is less than the 200*200 dimensions, you would get the image as the highest resolution avaiable eg: 128*160. Either you can resize it using the GD library.
AND ONE MORE THING
Facebook supports 200*600px as the highest resolution for the profile pic. It will resize an image to fit into these dimensions by maintaining the aspect ratio.
*UPDATE as on 19th Feb, 2017 *
We need to use this new URL formation to get a desired profile image.
http://graph.facebook.com/{profile_id}/picture?width={number‌​}&height={number}
[Thank you https://stackoverflow.com/users/2829128/vay]
If you want to get a larger picture you can just set the height and width you want like this:
http://graph.facebook.com/[page id/profile id]/picture?width=[number]&height=[number]
More info and examples here: Pictures - Facebook Developers
this will also work
picture.type(large)
example
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:#{#"fields": #"picture.type(large),name, email"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"fetched user:%#", result);
NSMutableDictionary *data=[[NSMutableDictionary alloc]init];
data=result;
fbId.text=[data valueForKey:#"id"];
userName.text=[data valueForKey:#"name"];
_emailFB.text=[data valueForKey:#"email"];
NSDictionary *dictionary = (NSDictionary *)result;
NSDictionary *data3 = [dictionary objectForKey:#"picture"];
NSDictionary *data2 = [data3 objectForKey:#"data"];
NSString *photoUrl = (NSString *)[data2 objectForKey:#"url"];
NSLog(#"Photo : %#",photoUrl);
}
}];
}
}
YES, there is a way to get the original (most of time bigger) profile picture of a facebook page.
Actually the answer is already in the question. The original image url is already embedded in the save_image url. In your case it is "url=http%3A%2F%2Fi52.tinypic.com%2F2q0ixzl.jpg” which means "http://i52.tinypic.com/2q0ixzl.jpg"
In my case, the page for London is
https://www.facebook.com/pages/London-United-Kingdom/106078429431815?fref=ts
I can easily get its fb object id by search keyword London.
I have tried to use width and height parameter. They work with user profile picture or user shared picture but can’t work with public pages profile picture.
https://graph.facebook.com/106078429431815/picture?width=300&height=300 // can’t work
The largest picture I can get it by following url which is only 180x77
https://graph.facebook.com/106078429431815/picture?type=large
But I can get safe_image.php url by using fb graph api, and the original image url is also inside the parameters' url section
"url": "https://fbexternal-a.akamaihd.net/safe_image.php?d=AQCrtKykRotXBuaS&w=180&h=540&url=http%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2Farchive%2F2%2F21%2F20141005220235%2521City_of_London_skyline_at_dusk.jpg%2F720px-City_of_London_skyline_at_dusk.jpg&fallback=hub_city&prefix=d"
Here is code I used.
[FBRequestConnection startWithGraphPath:[NSString stringWithFormat:#"/%#/picture?redirect=false&type=large",[firstCityPage objectForKey:#"id"]]
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
NSString *profileImgUrl = [NSString stringWithFormat:#"http://graph.facebook.com/%#/picture?type=large", [firstCityPage objectForKey:#"id"]];
if (error==nil) {
NSString *fbSaveImgUrl = [[(NSDictionary*)result objectForKey:#"data"] objectForKey:#"url"];
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:[NSURL URLWithString:fbSaveImgUrl]
resolvingAgainstBaseURL:NO];
for (NSURLQueryItem *queryItem in urlComponents.queryItems) {
if ([queryItem.name isEqualToString:#"url"]) {
profileImgUrl = queryItem.value;
break;
}
}
} else {
NSLog(#"%#",[error description]);
}
NSLog(#"url: %#", profileImgUrl);
...
}];
BUT, there are risks.
No guarantee the external image url will be validate.
Facebook may remove the explicit external url in the safe_image url or hide the safe_image url from developer in future.
Use it at your own risk.