Here i use GET method to fetch data from one Url and display the data in table view.I used synchronous to get data to display.
Needed:
I need to change this code to Asynchronous to display same data in table view.Here i just use my console to display data.
Here my code:
#import "ViewController.h"
#import <CommonCrypto/CommonDigest.h>
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self getdata];
}
-(NSString*)sha256HashFor:(NSString*)input
{
const char* str = [input UTF8String];
unsigned char result[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(str, strlen(str), result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++)
{
[ret appendFormat:#"%02x",result[i]];
}
return ret;
}
-(void)getdata {
NSString *userName = #"user#gmail.com";
NSString *password = #"passer";
//encoding
NSData *Data = [password dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [Data base64EncodedStringWithOptions:0];
base64String=[self sha256HashFor: base64String];
NSString *urlString = #"https://api.exampleurl/user23/doc";
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
NSString *authStr = [NSString stringWithFormat:#"%#:%#", userName, base64String];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64EncodedStringWithOptions:0]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(#"%#", str);
}
In this code i used base64 and shaa256 encoding.
Can any one help me to do with Asynchronous. I don't know how to do
that. please help me with code explain.
Thanks in advance!
For making Asynchronous http request you can use :
[NSURLConnection sendAsynchronousRequest:httpRequest queue:[AppDelegate connectionQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
....
}];
or you can implement NSURLConnectionDataDelegate protocol
Updated Answer :
First create a connection queue in app delegate file
+ (NSOperationQueue *)connectionQueue
{
dispatch_once(&once, ^{
connectionQueue = [[NSOperationQueue alloc] init];
[connectionQueue setMaxConcurrentOperationCount:2];
[connectionQueue setName:#"com.XYZ.connectionqueue"];
});
return connectionQueue;
}
Here is updated getData Method :
-(void)getdata {
NSString *userName = #"user#gmail.com";
NSString *password = #"passer";
//encoding
NSData *Data = [password dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [Data base64EncodedStringWithOptions:0];
base64String=[self sha256HashFor: base64String];
NSString *urlString = #"https://api.exampleurl/user23/doc";
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
NSString *authStr = [NSString stringWithFormat:#"%#:%#", userName, base64String];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64EncodedStringWithOptions:0]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
__block NSString *str;
[NSURLConnection sendAsynchronousRequest:httpRequest queue:[AppDelegate connectionQueue]completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
str = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];}];
NSLog(#"%#", str);
}
Related
I am new to IOS i need to know how to pass NSString as parameter in nsurlconnection POST method,i passed string but it become empty
viewdidload:
NSString *parseURL =#"http:url";
NSString *encodeurl =[parseURL stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:encodeurl];
NSData *data = [NSData dataWithContentsOfURL:url];
if(data){
NSError *error;
NSDictionary *json1 = [NSJSONSerialization JSONObjectWithData:data options: kNilOptions error:&error];
arrMsg = [json1 valueForKeyPath:#"Branches.branch_name"];
arrmsg1 =[json1 valueForKeyPath:#"Branches.id"];
NSString *str = [arrmsg1 componentsJoinedByString:#","];
NSLog(#"%#",str);
[self sendDataToServer :#"POST"];
}
post method:
In post method i passed the string as parameter
-(void) sendDataToServer : (NSString *) method{
//NSString *str = [arrmsg1 componentsJoinedByString:#","];
NSString *post = [NSString stringWithFormat:#"branch_id=%#",str];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[post length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URL]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLConnection *theConnection = [NSURLConnection connectionWithRequest:request delegate:self];
if( theConnection ){
// indicator.hidden = NO;
mutableData = [[NSMutableData alloc]init];
}
}
you can do like
arrMsg = [json1 valueForKeyPath:#"Branches.branch_name"];
arrmsg1 =[json1 valueForKeyPath:#"Branches.id"];
NSString *str = [arrmsg1 componentsJoinedByString:#","];
NSLog(#"%#",str);
// call the method like
[self sendDataToServer :#"POST" params:str];
// create the method like
-(void) sendDataToServer : (NSString *) method params:(NSString *)str{
NSString *post = [NSString stringWithFormat:#"branch_id=%#",str];
.... continue your work
}
I am having one url to get data and to display. Here I need to follow some steps for authAuthorization header: to base64,sha256 0r sha512
So here I coded to get data with Authorization header.But in my console I got error:
str: {
"error_code": "invalid_auth_header",
"message": "Invalid authorization. Use an auth header or access hash"
}
I am new to HTTP/GET, Authorization header and all. What am I doing wrong and what do I need to change there to work that out?
Here is my code (This is the update code based on the below answer):
#import "ViewController.h"
#import <CommonCrypto/CommonDigest.h>
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *userName = #"testingyouonit#gmail.com";
NSString *password = #"testingyouonit2";
NSData *plainData = [password dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [plainData base64EncodedStringWithOptions:0];
base64String=[self sha256HashFor: base64String];
//setting the string of the url taking from appliance IP.
NSString *urlString = #"https://api.exampleURL.com/files";
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
NSString *authStr = [NSString stringWithFormat:#"%#:%#", userName, base64String];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64Encoding]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(#"str: %#", str);
}
-(NSString*)sha256HashFor:(NSString*)input {
const char* str = [input UTF8String];
unsigned char result[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(str, strlen(str), result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++) {
[ret appendFormat:#"%02x",result[i]];
}
return ret;
}
First of all, please fix the following error in your code:
Change the base64String=[self sha256HashFor: password]; to base64String=[self sha256HashFor: base64String];.
NSString *str1 = [NSString stringWithFormat:#"https://api.exampleurl/user/data",userName,base64String]; to NSString *str1 = [NSString stringWithFormat:#"https://api.exampleurl/user/data"];
After that, to use a basic authorization use the following code:
NSString *authStr = [NSString stringWithFormat:#"%#:%#", userName, base64String];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64Encoding]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
I'm building an app around the Feedly API. So, in the UIWebView used to login, I use the following code:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *URLString = [[request URL] absoluteString];
NSString *urlStart = [URLString substringToIndex:23];
if ([urlStart isEqualToString:#"http://localhost/?code="])
{
NSString *haystack = request.URL.absoluteString;
[self useURL:haystack];
}
return YES;
}
As you can see, this calls a method useURL:
- (void)useURL:(NSString *)haystack {
NSString *prefix = #"http://localhost/?code=";
NSString *suffix = #"&state=";suffix!
NSRange needleRange = NSMakeRange(prefix.length,
haystack.length - prefix.length - suffix.length);
NSString *needle = [haystack substringWithRange:needleRange];
NSLog(#"needle: %#", needle);
NSString *valueToSave = needle;
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:#"AuthCode"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSString *client_id = #"id";
NSString *client_secret = #"secret";
NSString *redirect_uri = #"http://localhost";
NSString *state = #"";
NSString *grant_type = #"authorization_code";
NSInteger success = 0;
#try {
NSString *post =[[NSString alloc] initWithFormat:#"code=%#&client_id=%#&client_secret=%#&redirect_uri=%#&state=%#&grant_type=%#",needle,client_id,client_secret,redirect_uri,state,grant_type];
NSLog(#"PostData: %#",post);
NSURL *url=[NSURL URLWithString:#"https://cloud.feedly.com/v3/auth/token"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
//[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Response code: %ld", (long)[response statusCode]);
if ([response statusCode] >= 200 && [response statusCode] < 300)
{
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Response ==> %#", responseData);
NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization
JSONObjectWithData:urlData
options:NSJSONReadingMutableContainers
error:&error];
NSString *accessToken = jsonData[#"access_token"];
NSString *refreshToken = jsonData[#"refresh_token"];
//[self performSegueWithIdentifier:#"presentNewView" sender:self];
NewViewController *newView = [[NewViewController alloc] init];
[self presentViewController:newView animated:NO completion:nil];
} else {
NSLog(#"Failed.");
}
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
}
}
Most of it works fine up until the part where the next view should come in. I tried it with a segue and I tried the way as can be seen here, but both keep throwing Exception: *** -[NSURL initFileURLWithPath:]: nil string parameter
What am I doing wrong here?
As your error message states, you have a nil string. You can use breakpoints inside of the class and the LLDB to print the value of said string throughout its lifecycle, using po stringName in the debugger. Find where it looses the value, and you have your answer. Here are some helpful links to help you do this quickly if you're new to LLDB or breakpoints:
Breakpoints Guide
LLDB Commands
If you're more comfortable with using NSLog, placing them in the objects life cycle could be helpful as well, but I would go with the first recommendation.
I am trying to parse data for google translate. In viewdidload, I wrote the following code.
NSString * target = #"ja";
NSString * source = #"en";
NSString *textEscaped = #"Hi, How are u";
NSString *ke=#"My_key";
NSString * urlText =[NSString
key=%#&source=%#&format=text&target=%#&q=%#",ke,source,target,textEscaped];
NSURL *url = [NSURL URLWithString:urlText];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
[request setURL:url];
[request setHTTPMethod:#"GET"];
NSURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response
error:&error];
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#",result);
I compared my code with different sources and my API is also activated but I am getting nothing in result string. Its bill. Why?
Create Your url like this:
[NSString stringWithFormat:#"https://www.googleapis.com/language/translate/v2key=%#&target=%#&q=%#",key, target, selectedWord];
Currently I have a string that I want to POST to a URL.
It works perfectly fine except when it encounters special characters like "&", and "?". It will not POST any data that comes after that. For example, if I have a string "I am something & something?", it will only POST "I am something". As for "?", it will be converted to '2' after it has been posted.
reason = 'What see see! Are you sure'2''
I am pretty sure that it must have something to do with encoding as I can see "I am something & something?" as it is just before I set the encoding:
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding];
I have also tried the encodings below with no success:
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
NSData *postData = [post dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSData *postData = [post dataUsingEncoding:NSISOLatin1StringEncoding];
Below are my codes from postData onwards:
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding];
//NSLog(#"PostData: %#", postData);
NSString *check = [[NSString alloc] initWithData:postData encoding:NSASCIIStringEncoding];
NSLog(#"check string = %#", check);
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:strURLQueryString]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLResponse *response;
NSError *err=nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *strResponse = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"Response: %#", strResponse);
if(err!=nil) {
NSLog(#"Error: %#", [err description]);
}
Please assist.
Your help(s) are appreciated.
There's probably a better answer out there somewhere, but this class extension has been working for me for awhile. I cobbled together the % escapes by looking at a few posts...
// NSString+URLEncoding.h
#interface NSString (NSString_URLEncoding)
- (NSString *)urlEncodeUsingEncoding:(CFStringEncoding)encoding;
- (NSString *)urlEncode;
#end
// NSString+URLEncoding.m
#implementation NSString (NSString_URLEncoding)
- (NSString *)urlEncodeUsingEncoding:(CFStringEncoding)encoding {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(__bridge CFStringRef)self,
NULL,
CFSTR("!*'();:#&=+$,/?%#[]"),
encoding));
}
- (NSString *)urlEncode {
return [self urlEncodeUsingEncoding:kCFStringEncodingUTF8];
}
Then in somer other class to send a string...
// SomeOtherClass.m
#import "NSString+URLEncoding.h"
NSString *encodedString = [#"This & this? are 'challenging' to !% encode" urlEncode];