i am using singleton class for web service calling and display in uitableview ,My function is when i clicked submit button of new orchardname for new add then view redirect to tableview but data not seen which add recently. "singOrchard.orcharsList" it's orchard name array which i have to display. "[wOrchrad getorchardslist]" it's my web service call.
- (IBAction)Submit:(id)sender
{
if (Orchadname.text.length == 0) {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"DataTree" message:#"Please Enter OrchardName" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[message show];
}
else {
[singOrchard.orcharsList removeAllObjects];
NSString *urlStr = [NSString stringWithFormat:#"http://xyz.com"]; // Passing token to URL
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self]; // Support to perform URLrequest
if (theConnection) { // checking connection successfull or not
webData1 = [NSMutableData data];
NSLog(#"Orchard Name is %#", Orchadname.text);
}
[wOrchrad getorchardslist];
NSLog(#"ARRAY COUNT %#",singOrchard.orcharsList);
[self performSelector:#selector(gotodetails) withObject:nil afterDelay:4];
}
}
"[wOrchard getorchardslist]- Singletone+Webserviceutility"
- (void)getorchardslist
{
orchardsnames = [[NSMutableArray alloc] init];
singltoneclass = [SingletoneClass sharedInstanceMethod];
theRequest =[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.xyz.com"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
webData = [NSMutableData data];
[theConnection start];
}
You are not using the return result from theConnection. (At least not in your provided code.) Since you have set your class as the delegate, implement the NSURLConnectionDataDelegate methods.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
use it to save your JSON data to an NSArray, which you can then use in your UITableView.
If you send your request asynchrounsly, don't forget to append the data with
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
Related
My app is asking for permission to “Have offline access”, why? It's the weirdest thing. I've done a bit of searching and haven't really found anything that's worked. I've tried using these for scopes:
https://www.googleapis.com/auth/plus.profile.emails.read
https://www.googleapis.com/auth/plus.login
and that didn't seem to help.
Below is a screenshot and some of my code to help you see what's going on:
Some of my code:
#import "ViewController.h"
NSString *callbakc = #"http://localhost/";
NSString *client_id = #“CLIENT ID“;
NSString *scope = #"https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile+https://www.google.com/reader/api/0/subscription";
NSString *secret = #“SECRET”;
NSString *visibleactions = #"http://schemas.google.com/AddActivity";
#interface ViewController () {
NSString *authAccessToken;
UIAlertController *alertController;
}
#property (strong, nonatomic) NSMutableData *receivedData;
#property (weak, nonatomic) IBOutlet UIWebView *webView;
#end
#implementation ViewController
#pragma mark - Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
NSString *url = [NSString stringWithFormat:#"https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%#&redirect_uri=%#&scope=%#&data-requestvisibleactions=%#",client_id,callbakc,scope,visibleactions];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];
[_webView loadRequest:request];
}
#pragma mark - WebView Delegate
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
[self performSelector:#selector(progressDelay:) withObject:nil afterDelay:0.0];
if ([[[request URL] host] isEqualToString:#"localhost"]) {
// Extract oauth_verifier from URL query
NSString* verifier = nil;
NSArray* urlParams = [[[request URL] query] componentsSeparatedByString:#"&"];
for (NSString* param in urlParams) {
if (![param isEqualToString:#"error=access_denied"]) {
NSArray* keyValue = [param componentsSeparatedByString:#"="];
NSString* key = [keyValue objectAtIndex:0];
if ([key isEqualToString:#"code"]) {
verifier = [keyValue objectAtIndex:1];
// NSLog(#"verifier %#",verifier);
break;
}
}
else {
[self.navigationController popViewControllerAnimated:NO];
}
}
if (!verifier==0) {
[self showAlertViewWithTitle:#"" message:#"Please wait" okAction:NO];
NSString *data = [NSString stringWithFormat:#"code=%#&client_id=%#&client_secret=%#&redirect_uri=%#&grant_type=authorization_code", verifier,client_id,secret,callbakc];
NSString *url = [NSString stringWithFormat:#"https://accounts.google.com/o/oauth2/token"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPShouldHandleCookies:NO];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"Connection: %#", theConnection);
self.receivedData = [[NSMutableData alloc] init];
}
else {
// cancel button click
NSLog(#"not Verified!!");
}
return NO;
}
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
// show progress
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[alertController dismissViewControllerAnimated:YES completion:nil];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
if (error.code==102) //Frame load interrupted
return;
[alertController dismissViewControllerAnimated:YES completion:nil];
[self showAlertViewWithTitle:#"Error" message:[error localizedDescription] okAction:YES];
}
#pragma mark - NSURLConnection Delegate
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
[self showAlertViewWithTitle:#"Error" message:[NSString stringWithFormat:#"%#", error] okAction:YES];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *response = [[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding];
NSData *data = [response dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *tokenData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
if ([tokenData objectForKey:#"access_token"]) {
authAccessToken = [tokenData objectForKey:#"access_token"];
[self getUserInfo:authAccessToken];
}
else {
[alertController dismissViewControllerAnimated:YES completion:nil];
NSLog(#"RESULT: %#", tokenData);
[self showAlertViewWithTitle:[tokenData objectForKey:#"name"] message:[NSString stringWithFormat:#"%#", tokenData] okAction:YES];
// Flush all cached data
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
}
#pragma mark - Private Method Implementation
-(void)getUserInfo:(NSString *)token {
NSString *url = [NSString stringWithFormat:#"https://www.googleapis.com/oauth2/v1/userinfo?access_token=%#",token];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"GET"];
[request setHTTPShouldHandleCookies:NO];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"Connection: %#", theConnection);
self.receivedData = [[NSMutableData alloc] init];
}
-(void)progressDelay:(id)sender {
// Dismiss progress
}
#end
Any help would be greatly appreciated!
Thank you
This is from https://stackoverflow.com/questions/32210920/why-is-my-app-asking-for-permission-to-have-offline-access?answertab=oldest#tab-top:
This is normal behavior and occurs when the user has granted
permission already.
Basically, no need to worry about it unless you really don't want that
showing up, in that case, you need to un auth the users old token
before requesting a new one.
I'm not exactly sure how because I haven't done this before, but before you authorize a new token you need to un-authorize the old one.
You'll need to modify the -(void)getUserInfo:(NSString *)token method.
For some reason unknown to me. The email scope pops up with
Have offline access
If you want to remove the have offline access remove the email scope. Personally I think it is miss leading to users that you are asking for email access yet are prompted for offline access. Technically speaking all OAuth2 that returns a refresh token gives offline access so the user should always be told that you are getting offline access but it doesnt.
I'm trying to make a basic app that takes in a persons details and posts it on a private server. My URL is kept blank for now, If I use the NSURLConnectionDelegate and use didFailWithError, it works saying there's no connection but when I try the NSLog method it says
"connection is made"
for some reason. This is my code
- (void) saveData{
NSString *name = self.NameTextField.text;
NSString *phoneNumber = self.phoneNumberTextField.text;
NSString *age = self.ageTextField.text;
NSString *email = self.emailTextField.text;
//Define the URL
NSURL *url = [[NSURL alloc]initWithString:#""];
//Initialize a request from the URL
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[url standardizedURL]];
//Specify that it will be a post request.
request.HTTPMethod = #"POST";
// This is how we set header fields
[request setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSString *DataString = [NSString stringWithFormat:#"name=%#&phonenumber=%#&age=%#&email=%#",name,phoneNumber,age,email];
//Change your requests HTTPBody property
NSData *requestBodyData = [DataString dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = requestBodyData;
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.connection = conn;
if(self.connection){
NSLog(#"Connection is made");
}else{
NSLog(#"Connection is not made");
}
[self.connection start];
}
Do inform if theres any other mistake in my code.
All that if (self.connection) is doing is checking to see if it's nil it's not actually checking to see if a connection has been made you do that at [self.connection start];. So essentially:
if (self.connection) {
NSLog(#"Connection is made");
} else {
NSLog(#"Connection is not made");
}
is the exact same as
if (self.connection != nil) {
NSLog(#"Connection is made");
} else {
NSLog(#"Connection is not made");
}
And self.connection is not nil because you assign conn to it which has been initialized. This can be seen in the two lines below from your code.
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.connection = conn;
What you could do if you are wanting to check whether the connection was successful or not is check the HTTP Status code in didReceiveResponse: (Code obtained from Checking for valid IP for connection with NSURLConnection)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
switch ([(NSHTTPURLResponse *)response statusCode]) {
case 200: {
NSLog(#"Received connection response!");
break;
}
default: {
NSLog(#"Something bad happened!");
break;
}
}
}
OR if it's just to see whether you can or not you could implement the Reachability code that Apple supplies or use another open source version.
Your code checks whether the self.connection variable is not null, which it's not since the alloc init seems to have executed successfully. i.e the object is created and that is what you are checking, whether it does what you want is a different story.
I have 2 separate NSURLConnection.
NSURLConnection * connection_users;
NSURLConnection * connection_cards;
Then i created the data with parameters, etc. and I finish with:
connection_users = [[NSURLConnection alloc] initWithRequest: url_request_users delegate: self startImmediately: YES];
In the delegate method:
- (void) connection: (NSURLConnection *) connection didReceiveData: (NSData *) data
i Checked if the connection is for the connection_users:
if (connection == connection_users) / / do something as an example:
NSDictionary * json_response = [NSJSONSerialization JSONObjectWithData: data options: kNilOptions error: & error];
Use the "data" that came from the method.
Before closing the "if" I create the next connection to "connection_cards", doing the same things
Out of "if" but within the same method I do another "if" to "connection_cards" and do the same thing with JSONObjectWithData.
Only the "data" that comes from the method is always of the first connection.
What is happening differently? For the second connection was initiated then you should receive the "data" corresponding.
Already canceled the first connection before starting the second to see if solved, but no.
How to obtain the "data" correct for second connection?
PS: if you need more codes, please let me know.
EDITED:
As Wain ask
url_request_users = [[NSMutableURLRequest alloc] init];
NSMutableString *post_users = [[NSMutableString alloc] init];
[post_users appendFormat:#"%#", [NSString stringWithFormat:#"email=%#&senha=%#",
[[alert textFieldAtIndex:0] text],
senha_md5]];
[url_request_users setURL:[NSURL URLWithString:WBS_USERS_RECOVER]];
[url_request_users addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[url_request_users setHTTPMethod:#"POST"];
[url_request_users setHTTPBody:[post_users dataUsingEncoding:NSUTF8StringEncoding]];
connection_users = [[NSURLConnection alloc] initWithRequest:url_request_users delegate:self startImmediately:YES];
For n different connections you will need n different NSMutableData which contains result of related NSURLConnection. A basic example for your question;
NSMutableData *data_users;
NSMutableData *data_cards;
Than on your didRecieveData;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if (connection == connection_users) {
[data_users appendData:data];
} else if ( connection == connection_cards) {
[data_cards appendData:data];
}
}
This way you can keep track of your data's and connection's seperately. Remember to clear leftovers for your datas when your connection is over
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if (connection == connection_users) {
// use data from data_users
NSDictionary * json_response = [NSJSONSerialization JSONObjectWithData:[data_users copy] options: kNilOptions error: & error];
data_users = [[NSMutableData alloc] init]; // clear data users
}
// do the same for cards connection
}
Last thing to do is to allocate your data before you call this function;
url_request_users = [[NSMutableURLRequest alloc] init];
NSMutableString *post_users = [[NSMutableString alloc] init];
[post_users appendFormat:#"%#", [NSString stringWithFormat:#"email=%#&senha=%#",
[[alert textFieldAtIndex:0] text],
senha_md5]];
[url_request_users setURL:[NSURL URLWithString:WBS_USERS_RECOVER]];
[url_request_users addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[url_request_users setHTTPMethod:#"POST"];
[url_request_users setHTTPBody:[post_users dataUsingEncoding:NSUTF8StringEncoding]];
data_users = [[NSMutableData alloc] init]; // add this line in your code
connection_users = [[NSURLConnection alloc] initWithRequest:url_request_users delegate:self startImmediately:YES];
I have a UIImageView that is displaying an image using a URL, I have a download button that brings up a UIActionSheet which will then download the file using the URL i want to know how to do the coding for the download part of it using NSURLConnection.
- (IBAction)DownloadClick:(id)sender {
UIActionSheet *Action = [[UIActionSheet alloc]
initWithTitle:#"Options"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Download", nil];
[Action showInView:self.view];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) { //The Download code will go here This is where i need ur help
}
The Url is saved in a string named "Url".
I don't think you tried Google for this. Anyway, here is your code and don't forget to add NSURLConnectionDataDelegate,
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) { //The Download code will go here This is where i need ur help
//-------------------------------------------------------
NSURL *url = [NSURL URLWithString:#"your_data_url"];
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
NSLog(#"succeed...");
} else {
NSLog(#"Failed...");
}
//-------------------------------------------------------------------
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
}
Make use of asynchronous request for image download. It can also help you identify errors, if any during image downloading.
NSURL* url = [NSURL URLWithString:#"http://imageAddress.com"];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
UIImage* image = [[UIImage alloc] initWithData:data];
// do whatever you want with image
}
}];
If you need synchronous download you can try this code:
NSURL *imageUrl = [NSURL URLWithString:#"http://site.com/imageName.ext"];
NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
UIImage *image = [[UIImage alloc] initWithData:imageData];
Now you have an image that you can use.
If you need an asynchronous request I suggest you to read the NSURLConnectionDataDelegate, that helps you handle the download of the file.
I am making an iPhone app that will need to communicate with the Sendy API. I believe that it uses some kind of JSON, but I'm not really sure, nor do I know where to start. I'm particularly interested in the subscribe portion of the API. Basically, I need to know how to talk to the Sendy API from my app.
Any help is appreciated.
My code:
- (IBAction)submitButtonPressed:(id)sender
{
self.data = [[NSMutableData alloc] initWithLength:0];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.erwaysoftware.com/sendy/subscribe"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"john#test.com" forHTTPHeaderField:#"email"];
[request setValue:#"john" forHTTPHeaderField:#"name"];
[request setValue:#"LxxxxxxxxxxxxxxxxxxxxQ" forHTTPHeaderField:#"list"];
[request setValue:#"true" forHTTPHeaderField:#"boolean"];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
[conn start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.data setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d {
[self.data appendData:d];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Error", #"")
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"")
otherButtonTitles:nil] show];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseText = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];
// Do anything you want with it
NSLog(#"%#", responseText);
}
When the log happens, the string is empty. I know through breakpoints that the last method is called.
Looking at the API it's all just plain text response.
Since it's a POST you can use an NSURLConnection to compose the request. See this question for information on formatting the response.
An alternative is to use something like AFNetworking or RestKit that might be a little more friendly if you're doing more work with APIs.
I'm guessing you've already resolved this but in case anyone else gets stuck here (as I did) I thought I'd post what I did to get it to work.
The first thing you need to do is create a category called NSString+URLEncoding (or whatever) which is going to take your email and name fields from blah#blah.com and turn it into blah%40blah.com. I modified this from the handy blog post found here
#interface NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
#end
#import "NSString+URLEncoding.h"
#implementation NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding)));}
#end
Ok so now just import NSString+URLEncoding.h and add the following code and you'll be in business. This post helped me with this part
- (IBAction)submitButtonPressed:(id)sender
{
NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:#"http://stashdapp.com/sendy/subscribe"]];
[newRequest setHTTPMethod:#"POST"];
[newRequest setValue:#"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSString *email = #"name#domain.com";
NSString *name = #"First Lastname";
NSString *list = #"XXXXXXXXXXXXXXXXXX";
NSString *postData = [NSString stringWithFormat:#"email=%#&boolean=true&name=%#&list=%#", [email urlEncodeUsingEncoding:NSUTF8StringEncoding],[name urlEncodeUsingEncoding:NSUTF8StringEncoding],list];
[newRequest setHTTPBody:[postData dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:newRequest delegate:self];
[conn start];
}
You still include the delegate methods which you quoted in your question.
Hope it helps someone!