How to print NSMutableURLRequest using NSLog ?
.allHTTPHeaderFields returns a dictionary with the header content:
NSLog(#"%#", [request allHTTPHeaderFields]);
// {
// "Accept-Language" = "en;q=1";
// "Content-Length" = 190706;
// "Content-Type" = "multipart/form-data; boundary=Boundary+D90A259975186725";
// "User-Agent" = "...";
// }
Or for specific field:
NSString *field = #"Content-Type";
NSLog(#"%#",[request valueForHTTPHeaderField:field]);
// multipart/form-data; boundary=Boundary+D90A259975186725
Did you try with
NSLog(#" %#", myMutableURLRequest);
Related
Please help me i'm using below code to get file name.
Here i'm getting NSString from NSData where multipartData is NSMutableArray which contain NSData.
NSString* postInfo = [[NSString alloc] initWithBytes:[[multipartData objectAtIndex:1] bytes] length:[[multipartData objectAtIndex:1] length] encoding:NSUTF8StringEncoding];
I'm getting string like:
Printing description of postInfo:
Content-Disposition: form-data; name="file"; filename="??:??.PNG"
But It should be like:
Printing description of postInfo:
Content-Disposition: form-data; name="file"; filename="华语/華語.PNG"
Thanks in advance.
Obviously the server doesn't encode the response using UTF-8, but probably another Chinese-only encoding. You need to use the Content-Type header to detect which encoding it is, and then find the appropriate NSStringEncoding using the following code;
// set charset to the MIME charset you get from the server
CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef)(charset)));
Here is a detailed answer:
// getting the Content-Type header (e.g. "application/json; charset=utf-8")
NSString* header = [[response allHeaderFields] objectForKey:#"Content-Type"];
// getting the MIME type
NSString* charset = nil;
NSArray* contentTypeParts = [header componentsSeparatedByString:#";"];
NSInteger i = 0;
for (NSString* part in contentTypeParts) {
// ignoring first loop (e.g. "application/json")
if (i > 0) {
NSArray* partComponents = [part componentsSeparatedByString:#"="];
if ([partComponents count] == 2 && [#"charset" isEqualToString:[[partComponents objectAtIndex:0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]]) {
charset = [[partComponents objectAtIndex:1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
break;
}
}
i++;
}
// converting the MIME type to NSStringEncoding
NSStringEncoding stringEncoding = NSUTF8StringEncoding; // default to UTF8
if (charset) {
stringEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef)(charset)));
}
// finally you can convert your string properly!
NSString* postInfo = [[NSString alloc] initWithBytes:[[multipartData objectAtIndex:1] bytes] length:[[multipartData objectAtIndex:1] length] encoding:stringEncoding];
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.
I am using QuickBlox in my iOS app and trying to add data in Places table
QBLPlace *place = [QBLPlace place];
place.geoDataID = 34691;
place.photoID = 447;
place.title = [NSString stringWithFormat:#"%#",[aView.annotation title]];
place.address = #"London, Gadge st, 34";
place.placeDescription = #"My place description";
place.latitude = pinLocation.coordinate.latitude;
place.longitude = pinLocation.coordinate.longitude;
[QBLocation createPlace:place delegate:self];
but I am not able to add place. Below is the console log
RestRequest:
POST http://api.quickblox.com/places.xml
headers:{
"QB-SDK" = "iOS 1.3.1";
"Qb-Token" = c1191ff8ffbfdb79b11fba6bf2a4c054d2644de8;
"QuickBlox-REST-API-Version" = "0.1.1";
}
parameters:{
"place[address]" = "London, Gadge st, 34";
"place[description]" = "My place description";
"place[geo_data_id]" = 34691;
"place[photo_id]" = 447;
"place[title]" = "The Bridge Room";
}
raw body:place[address]=London%2C%20Gadge%20st%2C%2034&place[description]=My%20place%20description&place[geo_data_id]=34691&place[photo_id]=447&place[title]=The%20Bridge%20Room
2013-01-02 10:21:14.543 Chat.Points[10229:1d903] Query QBLPlaceCreateQuery DEALLOC
2013-01-02 10:21:14.551 Chat.Points[10229:1d903] Request finished, response:
RestResponse:
<QBASIHTTPRequest: 0xb40fc00>
headers:{
"Access-Control-Allow-Origin" = "*";
"Access-Control-Request-Method" = "*";
"Cache-Control" = "no-cache";
Connection = Close;
"Content-Length" = 116;
"Content-Type" = "application/xml; charset=utf-8";
Date = "Wed, 02 Jan 2013 04:51:14 GMT";
"QuickBlox-REST-API-Version" = "0.1.1";
Server = "nginx/1.0.15";
Status = "422 Unprocessable Entity";
"X-Rack-Cache" = "invalidate, pass";
"X-Request-Id" = 5ad6e7d628b4fbd931b7896058f012cd;
"X-Runtime" = "0.052140";
"X-UA-Compatible" = "IE=Edge,chrome=1";
}
body:<?xml version="1.0" encoding="UTF-8"?>
<errors type="array">
<error>No photo with such id found</error>
</errors>
The right way to create place is:
QBLPlace *place = [QBLPlace place];
place.geoDataID = 34691;
place.photoID = 447;
place.title = [NSString stringWithFormat:#"%#",[aView.annotation title]];
place.address = #"London, Gadge st, 34";
place.placeDescription = #"My place description";
[QBLocation createPlace:place delegate:self];
where:
geoDataID - ID of QBLGeoData object
photoID - ID of QBCBlob object
Your error says that you have to create file with photo and then connect it to place.
To upload file please use this code:
NSData *file = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Hotel47" ofType:#"png"]];
[QBContent TUploadFile:file fileName:#"Hotel47 Image" contentType:#"image/png" isPublic:YES delegate:self];
#pragma mark -
#pragma mark QBActionStatusDelegate
- (void)completedWithResult:(Result *)result{
// Upload file result
if(result.success && [result isKindOfClass:[QBCFileUploadTaskResult class]]){
// File uploaded, do something
QBCBlob *uploadedFile = ((QBCFileUploadTaskResult *)result).uploadedBlob;
NSUInteger photoID = uploadedFile.ID; // use this as photo IS for place
}else{
NSLog("errors=%#", result.errors);
}
}
To create GeoData please use next code:
QBLGeoData *geodata = [QBLGeoData geoData];
geodata.latitude = 23.2344;
geodata.longitude = -12.23523;
geodata.status = #"Hello, world";
[QBLocation createGeoData:geodata delegate:self];
#pragma mark -
#pragma mark QBActionStatusDelegate
- (void)completedWithResult:(Result *)result{
// Check-in result
if(result.success && [result isKindOfClass:QBLGeoDataResult.class]){
QBLGeoDataResult *checkinResult = (QBLGeoDataResult *)result;
NSUInteger geoDataID = checkinResult.geoData.ID; // your geo data ID
}else{
NSLog(#"errors=%#", result.errors);
}
}
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]);
}];
I want to ask about the iPhone application objective C problem.
I wrote a program to store the cookies and pass to another URL to retrieve the cookies.
However, I found that one of the return status code is 0. The content of the html is empty.
Can any one help me?
The following is my code.
// create a new mutable url
NSMutableURLRequest *request_get2 = [[[NSMutableURLRequest alloc] init] autorelease];
[request_get2 setURL:[NSURL URLWithString:#"http://www.example.com"]];
[request_get2 setHTTPMethod:#"GET"];
[request_get2 setValue:#"text/html; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request_get2 setValue:#"http://www.example.com" forHTTPHeaderField:#"Referer"];
[request_get2 setHTTPShouldHandleCookies:YES];
// cookiesString is a string, the format is "cookieName=cookieValue;"
[request_get2 setValue: (NSString *) cookiesString forHTTPHeaderField:#"Cookie"];
// doGet - response
NSHTTPURLResponse *response_get2 = nil;
NSError *error_get2 = nil;
NSData *responseData_get2 = [NSURLConnection sendSynchronousRequest:request_get2 returningResponse:&response_get2 error:&error_get2];
NSString *data_get2 = [[NSString alloc]initWithData:responseData_get2 encoding:NSUTF8StringEncoding];
NSString *responseURL_get2 = [[response_get2 URL] absoluteString]; // null value
NSString *responseTextEncodingName_get2 = [response_get2 textEncodingName]; // null value
NSString *responseMIMEType_get2 = [response_get2 MIMEType]; // null value
NSUInteger *responseStatusCode_get2 = [response_get2 statusCode]; //[responseStatusCode intValue]; // the status code is 0
Thank you very much
If you get a 0 for a response code, the response response_get2 probably was never initialized, which might point to a problem with the request unrelated to your web server.
You set error_get2, so check its value after the request is placed:
if (!error_get2) {
NSString *responseURL_get2 = [[response_get2 URL] absoluteString]; // null value
NSString *responseTextEncodingName_get2 = [response_get2 textEncodingName]; // null value
NSString *responseMIMEType_get2 = [response_get2 MIMEType]; // null value
NSUInteger *responseStatusCode_get2 = [response_get2 statusCode]; //[responseStatusCode intValue]; // the status code is 0
}
else {
NSLog(#"something went wrong: %#", [error_get2 userInfo]);
}