Twitter search for hashtag - iphone

I'm trying to parse tweets using Twitter Framework, so I write the following code and it's working fine, but it's not Synchronous.
Now I'm trying to get all the tweets from #iOS.
I have used the following code to get the search result for iOS hashtag:
-(void)fetchResults
{
// Do a simple search, using the Twitter API
TWRequest *request = [[TWRequest alloc] initWithURL:[NSURL URLWithString:
#"http://search.twitter.com/search.json?q=iOS%20&rpp=20&with_twitter_user_id=true&result_type=recent"]
parameters:nil requestMethod:TWRequestMethodGET];
// Notice this is a block, it is the handler to process the response
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
if ([urlResponse statusCode] == 200)
{
// The response from Twitter is in JSON format
// Move the response into a dictionary and print
NSError *error;
dict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
NSLog(#"Twitter response: %#", [dict description]);
[self filterTweets];
}
else
NSLog(#"Twitter error, HTTP response: %i", [urlResponse statusCode]);
}];
}
As a result I got this:
Twitter response: {
"completed_in" = "0.007";
"max_id" = 333837474914766848;
"max_id_str" = 333837474914766848;
page = 1;
query = quranRadios;
"refresh_url" = "?since_id=333837474914766848&q=quranRadios&result_type=recent";
results = (
{
"created_at" = "Mon, 13 May 2013 06:53:51 +0000";
"from_user" = YousefMutawe;
"from_user_id" = 324385406;
"from_user_id_str" = 324385406;
"from_user_name" = "Yousef N Mutawe \Uf8ff";
geo = "<null>";
id = 333837474914766848;
"id_str" = 333837474914766848;
"iso_language_code" = pt;
metadata = {
"result_type" = recent;
};
"profile_image_url" = "http://a0.twimg.com/profile_images/1533729607/20090719526_normal.jpg";
"profile_image_url_https" = "https://si0.twimg.com/profile_images/1533729607/20090719526_normal.jpg";
source = "<a href="http://twitter.com/download/iphone">Twitter for iPhone</a>";
text = "Testing #quranRadios #Mkalatrash";
},
{
"created_at" = "Sun, 12 May 2013 13:09:43 +0000";
"from_user" = YousefMutawe;
"from_user_id" = 324385406;
"from_user_id_str" = 324385406;
"from_user_name" = "Yousef N Mutawe \Uf8ff";
geo = "<null>";
id = 333569679484416000;
"id_str" = 333569679484416000;
"iso_language_code" = et;
metadata = {
"result_type" = recent;
};
"profile_image_url" = "http://a0.twimg.com/profile_images/1533729607/20090719526_normal.jpg";
"profile_image_url_https" = "https://si0.twimg.com/profile_images/1533729607/20090719526_normal.jpg";
source = "<a href="http://twitter.com/download/iphone">Twitter for iPhone</a>";
text = "#quranRadios :)";
}
);
"results_per_page" = 20;
"since_id" = 0;
"since_id_str" = 0;
}
So i use the following method to filter the result and to get the (Tweet,Username,and the User image):
-(void)filterTweets
{
NSArray *results = [dict objectForKey:#"results"];
//Loop through the results
int x =0;
for (NSDictionary *tweet in results)
{
// Get the tweet
NSString *twittext = [tweet objectForKey:#"text"];
NSString *twitPic = [tweet objectForKey:#"profile_image_url"];
NSString *userName = [tweet objectForKey:#"from_user"];
// Save the tweet to the twitterText array
[tweetsInfo addObject:(twittext)];
[tweetPics addObject:(twitPic)];
[imagesArray addObject:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[tweetPics objectAtIndex:x]]]]];
[userNameTweet addObject:userName];
x++;
//NSLog(#"tweet ooooooo ======> %#",twitPic);
countMe++;
}
[tweetsTable reloadData];
}
I'm not sure if i'm doing the right thing,so what would you recommend me to do? and how can i make it synchronized?
am new to programming iOS, please advice.
Thanks.

Related

Using the YouTube API and iPhone SDK, how would I get information about a search result?

I'm trying to simply search for videos using a query, which is working perfectly using the below code.
// Create a service object for executing queries
GTLServiceYouTube *service = [[GTLServiceYouTube alloc] init];
// Services which do not require sign-in may need an API key from the
// API Console
service.APIKey = #"AIzaSy...";
// Create a query
GTLQueryYouTube *query = [GTLQueryYouTube queryForSearchListWithPart:#"id,snippet"];
query.maxResults = 10;
query.q = searchBar.text;
query.videoEmbeddable = #"true";
query.type = #"video";
//query.country = #"US";
// Execute the query
GTLServiceTicket *ticket = [service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
// This callback block is run when the fetch completes
if (error == nil) {
GTLYouTubeSearchListResponse *products = object;
[videoArray removeAllObjects];
// iteration of items and subscript access to items.
for (GTLYouTubeSearchResult *item in products) {
NSMutableDictionary *dictionary = [item JSONValueForKey:#"id"];
NSLog(#"%#", [dictionary objectForKey:#"videoId"]);
YoutubeVideo *video = [[YoutubeVideo alloc]init];
[video setLblTitle:item.snippet.title];
//Get youtube video image
[video setImgIconURL:[NSURL URLWithString:item.snippet.thumbnails.defaultProperty.url]];
[video setLblVideoURL:[dictionary objectForKey:#"videoId"]];
[video setLblChannelTitle:item.snippet.channelTitle];
[videoArray addObject:video];
}
reloadData = YES;
[tableView reloadData];
//Download images asynchronously
[NSThread detachNewThreadSelector:#selector(downloadImages)
toTarget:self
withObject:nil];
}else{
NSLog(#"Error: %#", error.description);
}
}];
However, now I'd like to display certain information about the video. Some of this information I can get out of
item.snippet
But I also need to get the video duration, and number of views. How can I get them using Youtube API 3.0?? I also had an idea to try using GData just for this, but it literally triples the load time to use
NSString *JSONString = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://gdata.youtube.com/feeds/api/videos/%#?v=2&alt=json", [video lblVideoURL]]] encoding:NSUTF8StringEncoding error:nil ];
How do I get the duration of the video, plus the number of views the video has?
Search query only accept ID and Snippet as parts. If you change to Video List Query you can include other parts, but you have to use one of the filters.
I think you'll have to get the video ID with the search query and do another query (Now a video query) filtering by ID (the Id you got), than you can get all other information of the videos you searched.
The problem is i'm having trouble getting the video ID, i think the API use the word "identifier" instead of "id" because it's a reserved word of objective-c.
Edit: Yeah, it was just a matter of time, just request my GTLYoutubeSearchResponse.JSON, an manipulated it as i wanted.
FIRST QUERY:
GTLQueryYouTube *query = [GTLQueryYouTube queryForSearchListWithPart:#"id,snippet"];
query.maxResults = 10;
query.q = #"iphone";
query.fields = #"items(id,snippet)";
query.order = #"viewCount";
//query.channelId = #"UCsnbNwitAF9BzjjdMfRyK2g";//Kavaco
[appDelegate.service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
id object,
NSError *error) {
if (error == nil) {
appDelegate.videos = object;
[self performSegueWithIdentifier:#"videoList" sender:self];
}
else {
NSLog(#"%#", error.description);
}
}];
SECOND QUERY: In my TableViewController, inside my cellForRowAtIndexPath i do another query for each video i found. Be sure to request only the variables you need to avoid spending your credits, in my case i requested only viewCount.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell" forIndexPath:indexPath];
GTLYouTubeVideo *video = appDelegate.videos[indexPath.row];
NSMutableDictionary *videoIdJson = [video.JSON objectForKey:#"id"];
NSString *videoId = [videoIdJson objectForKey:#"videoId"];
cell.textLabel.text = video.snippet.title;
GTLQueryYouTube *query = [GTLQueryYouTube queryForVideosListWithPart:#"statistics"];
query.identifier = videoId;
query.maxResults = 1;
query.fields = #"items/statistics(viewCount)";
[appDelegate.service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
id object,
NSError *error) {
if (error == nil) {
GTLYouTubeVideoListResponse *detalhe = object;
NSMutableDictionary *responseJSON = detalhe.JSON;
NSArray *tempArray = [responseJSON objectForKey:#"items"];
NSMutableDictionary *items = tempArray[0];
NSMutableDictionary *statistics = [items objectForKey:#"statistics"];
_views = [[NSString alloc] initWithFormat:#"Views: %#",[statistics objectForKey:#"viewCount"]];
cell.detailTextLabel.text = _views;
}
else {
NSLog(#"%#", error.description);
}
}];
cell.detailTextLabel.text = _views;
return cell;
}
Hope it helps.
Collect the id from search API and do another video list API call is the proper way to do what you want to achieve. The video list API call can put multiple video ids separate by comma in the same call. The extra call shouldn't consider exhausting because this is expected behavior on API v3:
Project Member #1 je...#google.com
That's the expected behavior, and not likely to change. Since the
search.list() method can return channels, videos, and playlists, only
properties that make sense for all of those resource types are
returned in the search responses. If you need to obtain any other
properties, making a follow-up request to, e.g., videos.list() is
required. Note that you can pass in up to 50 video ids to
videos.list(), so you can effectively look up an entire page's worth
of search.list() results in a single video.list() call.
If you try https://developers.google.com/youtube/v3/docs/videos/list#try-it , you set contentDetails,statistics as the part, you should able to get the following result:
"contentDetails": {
"duration": "PT20M38S",
"dimension": "2d",
"definition": "hd",
"caption": "false",
"licensedContent": false
},
"statistics": {
"viewCount": "191",
"likeCount": "7",
"dislikeCount": "0",
"favoriteCount": "0",
"commentCount": "0"
}
PT20M38S means 20 minutes and 38 seconds, based on ISO 8601(http://en.wikipedia.org/wiki/ISO_8601)
The best way for make this is:
if (!service) {
service = [[GTLServiceYouTube alloc] init];
service.shouldFetchNextPages = YES;
service.shouldFetchInBackground = YES;
service.retryEnabled = YES;
service.APIKey = #"AIzaSyDSO2JPnM_r9VcDrDJJs_d_7Li2Ttk2AuU";
}
[youtubeList removeAllObjects];
GTLQueryYouTube *query = [GTLQueryYouTube queryForSearchListWithPart:#"id"];
query.maxResults = 50;
query.q = withText;
query.fields = #"items(id)";
query.order = #"viewCount";
query.type = #"video";
// query.videoDuration = #"long";//any-long-medium-short
__block NSInteger incrementRequest = 0;
[service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
if (error) {
NSLog(#"Error is!! = %#", error.localizedDescription);
return;
}
GTLYouTubeVideoListResponse *idsResponse = object;
for (GTLYouTubeVideoListResponse *videoInfo in object) {
[youtubeList addObject:videoInfo.JSON];
GTLQueryYouTube *query2 = [GTLQueryYouTube queryForVideosListWithIdentifier:[[videoInfo.JSON valueForKey:#"id"] valueForKey:#"videoId"] part:#"id,contentDetails,snippet,statistics"];
query2.maxResults = 1;
query2.fields = #"items(id,contentDetails,snippet,statistics)";
query2.order = #"viewCount";
[service executeQuery:query2 completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
if (error) {
NSLog(#"Error is!! = %#", error.localizedDescription);
return;
}
GTLYouTubeVideoListResponse *detalhe = object;
for (NSMutableDictionary *tmpDict in youtubeList) {
if ([[[tmpDict valueForKey:#"id"] valueForKey:#"videoId"] isEqualToString:[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"id"]]) {
[tmpDict removeObjectForKey:#"id"];
//condition personal
if (![Utils parseISO8601TimeIsGrater30:[[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"contentDetails"] valueForKey:#"duration"]]) {
BOOL isBlockedInUs = NO;
for (NSString *countryRestric in [[[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"contentDetails"] valueForKey:#"regionRestriction"] valueForKey:#"blocked"]) {
if ([countryRestric isEqualToString:#"US"]) {
isBlockedInUs = YES;
break;
}
}
if (!isBlockedInUs) {
[tmpDict addEntriesFromDictionary:detalhe.JSON];
[tmpDict setValue:[[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"snippet"] valueForKey:#"publishedAt"] forKey:#"publishedAt"];
} else {
[youtubeList removeObject:tmpDict];
}
} else {
[youtubeList removeObject:tmpDict];
}
break;
}
}
incrementRequest ++;
if ([idsResponse.items count] == incrementRequest) {
//Finish
[self.tableView reloadData];
}
}];
}
}];

facebook graph api in ios error- Unknown path components

i am using facebook graph api in ios to share a news feed from iphone. But i get the following error:
{com.facebook.sdk:ParsedJSONResponseKey={
body = {
error = {
code = 2500;
message = "Unknown path components: /http://newswatch.nationalgeographic.com/2013/01/20/top-25-wild-bird-photographs-of-the-week-34;
type = OAuthException;
};
};
code = 400;
}, com.facebook.sdk:HTTPStatusCode=400}
following is part of my code to share a newsfeed on btnClick:
if ([strType isEqualToString:#"link"]) {
text = [[resultArrFeed objectAtIndex:selectedIndex] objectForKey:#"caption"];
if (text == nil) {
text = [[resultArrFeed objectAtIndex:selectedIndex] objectForKey:#"name"];
}
if (text == nil) {
text = [[resultArrFeed objectAtIndex:selectedIndex] objectForKey:#"story"];
}
NSDictionary *dict = [resultArrFeed objectAtIndex:selectedIndex];
dic=[NSDictionary dictionaryWithObjectsAndKeys:text,#"message",nil];
NSLog(#"%#", dict);
// NSString *str = [dict valueForKey:#"link"];
NSString *str = [dict valueForKey:#"link"];
request=[NSMutableString stringWithString: #"me/feed/"];
[request appendString:str];
NSLog(#"appended : %#", request);
}
same code works if i try to share a photo type of newsfeed. where am i getting wrong? how do i solve this problem?
i got the error: correct code:
if ([strType isEqualToString:#"link"] || [strType isEqualToString:#"video"]) {
text = [[resultArrFeed objectAtIndex:selectedIndex] objectForKey:#"caption"];
if (text == nil) {
text = [[resultArrFeed objectAtIndex:selectedIndex] objectForKey:#"name"];
}
if (text == nil) {
text = [[resultArrFeed objectAtIndex:selectedIndex] objectForKey:#"story"];
}
NSDictionary *dict = [resultArrFeed objectAtIndex:selectedIndex];
NSLog(#"%#", dict);
NSString *str = [dict valueForKey:#"link"];
dic=[NSDictionary dictionaryWithObjectsAndKeys:str,#"link",nil];
request=[NSMutableString stringWithString: #"me/feed/"];
NSLog(#" %#", dic);
}
in request we only need to pass me/feed and in params of FBRequest *friendRequest = [FBRequest requestWithGraphPath:request parameters:dic HTTPMethod:#"POST"]; we need to pass link=http://...

AFNetwork and GoogleAPI returning NULL

After being very disappointed with CLGeocoder, I decided to use the GoogleMaps API instead.
I have designed the call as following, using AFNetwork :
AFHTTPClient *new = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://maps.googleapis.com/"]];
NSDictionary *dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"thorsgade",#"true", nil] forKeys:[NSArray arrayWithObjects:#"address",#"sensor", nil]];
NSMutableURLRequest *req = [new requestWithMethod:#"GET" path:#"maps/api/geocode/json" parameters:dict];
AFJSONRequestOperation *call = [AFJSONRequestOperation JSONRequestOperationWithRequest:req success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSArray *geos = [JSON objectForKey:#"results"];
DLog(#"Got result : '%#' %# from %# %# %#",JSON,geos,[NSHTTPURLResponse localizedStringForStatusCode:response.statusCode],response.allHeaderFields,request.URL.description);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
DLog(#"Failed %# %#",error.localizedDescription,request.URL.description);
}];
[call start];
I get this feedback:
Got result : '(null)' (null) from no error {
"Cache-Control" = "public, max-age=86400";
"Content-Encoding" = gzip;
"Content-Length" = 1603;
"Content-Type" = "application/json; charset=UTF-8";
Date = "Fri, 07 Dec 2012 08:51:58 GMT";
Expires = "Sat, 08 Dec 2012 08:51:58 GMT";
Server = mafe;
Vary = "Accept-Language";
"X-Frame-Options" = SAMEORIGIN;
"X-XSS-Protection" = "1; mode=block"; } http://maps.googleapis.com/maps/api/geocode/json?sensor=true&address=thorsgade
Null result, but no errors. The content is recognized in the headers as JSON, but the raw JSON is null.
The annoying thing is that if I open http://maps.googleapis.com/maps/api/geocode/json?sensor=true&address=thorsgade in a browser, i get plenty of results.
So far i have tried:
Flicking the sensor booleon true/false.
Faking the user-agent to be regular safari.
Use POST instead of GET.
With no luck...
If the problem persists, I would recommend using MKNetworkKit instead
Here is my solution -
GoogleGeocodeApi.h
//GoogleGeocodeApi.h
#import <Foundation/Foundation.h>
#import "MKNetworkEngine.h"
typedef void (^JsonResponseBlock)(NSDictionary *);
typedef void (^ErrorBlock)(NSError* error);
#interface GoogleGeocodeApi : MKNetworkEngine
-(MKNetworkOperation*) geocodeWithAddress: (NSString *) address
onCompletion:(JsonResponseBlock) completionBlock
onError:(ErrorBlock) errorBlock;
#end
GoogleGeocodeApi.m
//GoogleGeocodeApi.m
#import "GoogleGeocodeApi.h"
#implementation GoogleGeocodeApi
-(id)init
{
if (self = [super initWithHostName:#"maps.googleapis.com" apiPath:#"maps/api/geocode" customHeaderFields:nil]) {
}
return self;
}
-(MKNetworkOperation*) geocodeWithAddress: (NSString *) address
onCompletion:(JsonResponseBlock) completionBlock
onError:(ErrorBlock) errorBlock;
{
MKNetworkOperation *op = [self operationWithPath:[NSString stringWithFormat:#"json?sensor=true&address=%#", address] params:nil httpMethod:#"GET"];
[op onCompletion:^(MKNetworkOperation *completedOperation) {
NSDictionary *responseJSON = [completedOperation responseJSON];
if (responseJSON && [[responseJSON objectForKey:#"status"] isEqualToString:#"OK"]) {
completionBlock(responseJSON);
} else {
NSDictionary* errorDictionary = #{NSLocalizedDescriptionKey :#"Google geocode failed!"};
NSError *error = [NSError errorWithDomain:#"Failed response" code:100 userInfo:errorDictionary];
errorBlock(error);
}
} onError:^(NSError* error) {
errorBlock(error);
}];
[self enqueueOperation:op];
return op;
}
Somewhere in code
GoogleGeocodeApi *gma = [[GoogleGeocodeApi alloc] init];
[gma geocodeWithAddress:#"thorsgade"
onCompletion:^(NSDictionary *responseJSON) {
NSLog(#"Geocode succeeded: %#", responseJSON);
} onError:^(NSError *error) {
NSLog(#"Geocode failed with error: %#", [error localizedDescription]);
}];

Problem Comparing Value Returned by valueForKey Method of NSDictionary

I use TouchJSON to convert the following to an NSDictionary object
// sample JSON object
{
data = (
{
companyId = 4779;
companyName = "ABC Corporation";
},
{
companyId = 4806;
companyName = "EFG Corporation";
}
);
dataCount = 2;
success = 1;
}
NSString *src = #"http://mysite/app1/companyList.php";
NSURL *url = [[NSURL alloc] initWithString:src];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *dic = [[CJSONDeserializer deserializer] deserializeAsDictionary:data error:&error];
int dataCount = (int) [dic valueForKey:#"dataCount"];
// This is where I have problem with. The (dataCount == 1) expression never evaluates to true even if value of dataCount from the JSON object equals to 1.
if ( dataCount == 1 ){
// do something
} else {
// do something else
}
Have I done anything wrong?
I'd appreciate any help.
[dic valueForKey:#"dataCount"] will be an NSNumber. You'll need to call -intValue on it to get an int.
int dataCount = [[dic valueForKey:#"dataCount"] intValue];
if (dataCount == 1) {
...
}

how to post with json

Hello I want to set following key Values for Dictionary
{
application = {
id = 136664723060869;
name = Iphoneapp;
};
caption = "bit.ly";
comments = {
count = 2;
data = (
{
"created_time" = "2011-06-14T07:39:45+0000";
from = {
id = 100001507678574;
name = "Widevision Dev";
};
id = "100001507678574_164163733643881_1822049";
likes = 1;
message = hi;
},
{
"created_time" = "2011-06-14T08:17:31+0000";
from = {
id = 100001507678574;
name = "Widevision Dev";
};
id = "100001507678574_164163733643881_1822143";
message = hmmm;
}
);
};
I want to post comments ={ data ={ id = , name = }}
I used following code for this
NSMutableDictionary *variables = [NSMutableDictionary dictionaryWithCapacity:4];
[variables setObject:#"Good Afternoon" forKey:#"message"];
NSLog(#"%#",variables);
FbGraphResponse *fb_graph_response = [fbGraph doGraphPost:#"id/comments" withPostVars:variables];
NSLog(#"postMeFeedButtonPressed: %#", fb_graph_response.htmlResponse);
But this not working....How can I post message in comment object
Please check the code below:
NSMutableDictionary *comments = [[NSMutableDictionary alloc] init];
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
NSMutableDictionary *from = [[NSMutableDictionary alloc] init];
[from setObject:#"100001507678574" forKey:#"id"];
[from setObject:#"Widevision Dev" forKey:#"name"];
[data setObject:from forKey:#"from"];
[comments setObject:data forKey:#"comments"];
NSLog(#"%#",comments);
FbGraphResponse *fb_graph_response = [fbGraph doGraphPost:#"id/comments" withPostVars:comments];