I have tried to find a similar question but I was unable to do so. I have a singleton that is used to gather information through out my app. Once of the values is obtained within the following method.
-(NSString *)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data-(NSString *)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
In this method I get the response from th webservice that I am trying to connect to. Everything is good. However any attempt to save the variable value to my singleton fails. Within this method no problem. When I try to get to the next view and reference my singleton, it is as if the value never gets saved.
Here is a skeleton of my code.
NBXJSONResponse *jsonResponse = [NBXJSONResponse sharedHostedResponseSingleton];
[jsonResponse setHostedURL:_hostedURL];
Basically the goal here is to have the hosted payment page appear in the next view. The flow flow for that works. I just need to pass the URI link so that payment can be made.
I know that I can return a value from this delegate method, but since I never explicitly call this method, so I am unsure where it is being called. Probably the reason why my values are not being saved in the singleton class.
EDIT:
Right now I have one view which does all of the action.
//
// NBXViewController.h file
#import <UIKit/UIKit.h>
#interface NBXViewController : UIViewController
//*************************************************
// Variables to be declared for NBXViewController *
//*************************************************
#property (strong, nonatomic) IBOutlet UILabel *storeLabel;
#property (strong, nonatomic) IBOutlet UIButton *purchaseButton;
#property (strong, nonatomic) IBOutlet NSString *hostedURL;
//*************************************************
// Button Action methods for the buttons on View *
//*************************************************
- (IBAction)puchaseButtonAction:(id)sender;
//*************************************************
// Connection Delegate Methods *
//*************************************************
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; // Handle Connection Error
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; // Data Received from Connection (Header Information)
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response; //Response from Connection (Return from Hosted being called)
-(void)connectionDidFinishLoading:(NSURLConnection *)connection; // Coonection did finish loading
#end
Implementation file.
//
// NBXViewController.m
// HostedAPI
//
// Created by Philip Teoli on 3/1/2014.
// Copyright (c) 2014 Philip Teoli. All rights reserved.
//
#import "NBXViewController.h"
#import "NBXJSONResponse.h"
#interface NBXViewController ()
#end
#implementation NBXViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//****************************************
// PurchaseButton Action Method *
//****************************************
- (IBAction)puchaseButtonAction:(id)sender
{
//************************************
// Building JSON Request *
//************************************
NSString *jsonString = #"Sample Request";
//**************************************
// Convert JSON String to NSData *
//**************************************
NSData* jsonRequestData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
//**************************************
// Creating JSON object to Send *
//**************************************
NSString *jsonRequest = [[NSString alloc] initWithData:jsonRequestData encoding:NSUTF8StringEncoding];
//*****************************************
// Base64 Encoding for Application Header *
//*****************************************
NSString *base64Signature = #"NbMIIkomZ8mFNw97EGRT:NAA5e965731e8a27ab11f5f";
NSString *basic = #"Basic: ";
NSData *base64SignatureData = [base64Signature dataUsingEncoding: NSUTF8StringEncoding];
NSString *base64SignatureEncoded = [base64SignatureData base64EncodedStringWithOptions:0];
NSString *header = nil;
header = [basic stringByAppendingString:base64SignatureEncoded];
// NSLog(#"Encoded Header: %#", header);
//*************************************
// Preparing to send XML through POST *
//*************************************
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[jsonRequest length]]; //Calculating the Content Length
NSData *postData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding]; // preapring JSON Request to be sent
//**************************************
// Headers and POST Body *
//**************************************
NSURL *serviceUrl = [NSURL URLWithString:#"https://pay.test.ewbservice.com/orders"];
NSMutableURLRequest *serviceRequest=[NSMutableURLRequest requestWithURL:serviceUrl cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
[serviceRequest setValue:postLength forHTTPHeaderField:#"Content-Length"];
[serviceRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[serviceRequest setValue:header forHTTPHeaderField:#"Authorization"];
[serviceRequest setHTTPMethod:#"POST"];
[serviceRequest setHTTPBody:postData];
NSURLConnection *connection = [[NSURLConnection alloc]
initWithRequest:serviceRequest
delegate:self startImmediately:YES];
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
[connection start];
NSLog(#"Hosted URL in Button: %#", _hostedURL);
}
//****************************************************
// Implementation of Connection Delegate Methods *
//****************************************************
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"did fail");
}
//*******************************************************
// Connection Data Received *
//*******************************************************
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString *dataResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *error = nil;
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData: [dataResponse dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
//********************************
// Iterating through Dictionary *
//********************************
NSArray *jsonLink = nil;
for(id key in jsonDictionary)
{
if ([key isEqualToString:#"link"])
{
jsonLink = [jsonDictionary objectForKey:key]; // this returns a dictionary. Will need to parse dictionary another 2 times to get proper URI.
}
}
NSDictionary *test = [jsonLink objectAtIndex:0];
for(id key in test)
{
if ([key isEqualToString:#"uri"])
{
_hostedURL = [test objectForKey:key];
}
}
NBXJSONResponse *jsonResponse = [NBXJSONResponse sharedHostedResponseSingleton];
[jsonResponse setHostedURL:_hostedURL];
}
//*******************************************************
// Connection Response Method *
//*******************************************************
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"did receive response: \n %#", response);
NBXJSONResponse *jsonResponse = [NBXJSONResponse sharedHostedResponseSingleton];
[jsonResponse setHostedURL:_hostedURL];
}
//*******************************************************
// Connection Finished Loading Data Method *
//*******************************************************
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"did finish loading!!! \n%#", _hostedURL);
// NBXJSONResponse *jsonResponse = [NBXJSONResponse sharedHostedResponseSingleton];
// [jsonResponse setHostedURL:_hostedURL];
}
#end
Please let me know of your thoughts. I can post more details if needed. Thanks in advance for your help!!!
Regards,
Thanks to the great help from #rdelmar I was able to get through this. Basically in short what was happening was that I was going to the next view before the information was received by my previous view from the web service. So when I was trying to change a label with a value to my Singleton, it was not stored yet. How I got around the issue is that when I click a button I wait until the web services responses and then I add a view to go to the new view. Now my URL that I was waiting reaches me, I save it to Singleton and then I go to the next view.
I will add my code once I can grab it and post it.
Thanks again for all of your help Eric!!! Your patience and help make you a great person on this community.
Regards,
Corporate One
Related
I've tried most of advises from stackoverflow but none of them was good for me.
My client wants to save user data in json with GET request in format:
http://website.com/users/save.php?save={"email":"user#domen.com","name":"Will Smith"}
I'm using objective-c
Please advise
Thanks
Edit
my php file looks like this:
<?php
$save = $_GET['save'];
$fp = fopen("save_users_ww.txt", "a+");
fputs($fp,$save."\r\n");
fclose($fp);
?>
so post don't work for me. Thank you for help again
In case someone else will need a solution, this is my code:
.h file:
#interface WelcomeViewController : UIViewController <NSURLConnectionDelegate>
{
NSMutableData *_responseData;
}
.m file:
-(void)postToDataBaseWithName:(NSString*)nameToPost andEmail:(NSString*)emailToPost {
NSString *str = [NSString stringWithFormat:#"http://website.com/users/save.php?save={\"email\":\"%#\",\"name\":\"%#\"}", emailToPost, nameToPost];
str = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:str];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(conn) {
}
}
also add delegate methods to see how it works:
#pragma mark NSURLConnection Delegate Methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// A response has been received, this is where we initialize the instance var you created
// so that we can append data to it in the didReceiveData method
// Furthermore, this method is called each time there is a redirect so reinitializing it
// also serves to clear it
NSLog(#"didReceiveResponse");
_responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the new data to the instance variable you declared
NSLog(#"didReceiveData");
[_responseData appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
// Return nil to indicate not necessary to store a cached response for this connection
return nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
NSLog(#"connectionDidFinishLoading");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// The request has failed for some reason!
// Check the error var
NSLog(#"didFailWithError = %#", error);
}
I am calling the webservice string using the NSURLConnection , I am getting wrong data in response in success method of NSURLConnection , But if i load same URL in browser i am getting correct response. I am using below code .
NSData *mydata=[srtRes dataUsingEncoding:NSUTF8StringEncoding];
NSError *e;
NSMutableArray *returnArry =[[NSMutableArray alloc]init];
returnArry = [NSJSONSerialization JSONObjectWithData:mydata options:NSJSONReadingMutableContainers error:&e];
How to resolve this issue. Kindly give suggestion and answers.
Try this one :
// In .h class
#property (nonatomic,retain) NSMutableData *responseData;
#property (nonatomic, retain) NSMutableArray *temp_arr;
// In .m class
#synthesize responseData;
#synthesize temp_arr;
- (void)viewDidLoad
{
NSString *urlString=#"http://your urls";
self.responseData=[NSMutableData data];
NSURLConnection *connection=[[NSURLConnection alloc]initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] delegate:self];
NSLog(#"connection====%#",connection);
}
Delegate Method of JSON Parsing :
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[self.responseData setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.responseData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
self.responseData=nil;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSArray * returnArry = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:nil];
NSDictionary *nameDic = nil;
for (int i = 0 ; i < [returnArry count]; i++)
{
nameDic = [returnArry objectAtIndex:i];
[self.temp_arr addObject:[nameDic objectForKey:#"name"]]; // According your key you have to save data in temp_arr.
}
}
Please follow this , if any doubt let me know :)
-(IBAction)onButtonClick:(id)sender
{
DowloadFilesManager* downManager1=[[DowloadFilesManager alloc] init];
DowloadFilesManager* downManager2=[[DowloadFilesManager alloc] init];
DowloadFilesManager* downManager3=[[DowloadFilesManager alloc] init];
[downManager1 downloadURL:#"http://localhost/banners/banner1.jpg" destPath:#"/Users/varunisac/Desktop/samples/godisgreat.jpg"];
[downManager2 downloadURL:#"http://localhost/banners/banner1.jpg" destPath:#"/Users/varunisac/Desktop/samples/godisgreat1.jpg"];
[downManager3 downloadURL:#"http://localhost/banners/banner1.jpg" destPath:#"/Users/varunisac/Desktop/samples/godisgreat2.jpg"];
NSLog(#"Finished Succesfully");
}
1)The Above code works Perfect
2) It downloads the jpgs after firing the following event function.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Succeeded! Received %d bytes of data",[receivedData length]);
[receivedData writeToFile:toFile atomically:YES];
theConnection = nil;
receivedData = nil;
}
But It DOES NOT fires any event methods while i tried on another programme after importing the "DowloadFilesManager.h" and "DowloadFilesManager.m" which runs on the same XCode on the same Mac machine with the server URLs reachable.Can anyone suggest a solution ? Am i missing anything? I tried Clean etc...but doesnt work. Following is the DowloadFilesManager class which i used:
#import "DowloadFilesManager.h"
#implementation DowloadFilesManager
#synthesize toFile;
#synthesize toURL;
#synthesize theConnection;
-(void) downloadURL:(NSString *) urlStr destPath:(NSString *) destPath
{
toURL=urlStr;
toFile=destPath;
// Create the request.
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:toURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
receivedData = [[NSMutableData alloc] init];
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
// [receivedData dataWithCapacity: 0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (!theConnection) {
// Release the receivedData object.
receivedData = nil;
// Inform the user that the connection failed.
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the new data to receivedData.
// receivedData is an instance variable declared elsewhere.
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
theConnection = nil;
receivedData = nil;
// inform the user
NSLog(#"Connection failed! Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Succeeded! Received %d bytes of data",[receivedData length]);
[receivedData writeToFile:toFile atomically:YES];
theConnection = nil;
receivedData = nil;
}
#end
Within - (void)downloadURL:destPath:, you have created a local variable called theConnection:
NSURLConnection *theConnection = [...];
and when the method ends, this will go out of scope and be destroyed.
What you want is the following, to use your property to persist the connection object:
self.theConnection = [...];
Also, a better approach to signal failure would be to make that method return BOOL and use this statement:
return self.theConnection != nil;
I can't figure out why my code isn't working. I think I'm doing everything correctly, the php script encodes and displays how it should. Can someone please look over my code and suggest what I'm doing wrong?
PHP:
$link = ...succesfully connects
if ($link){
if (isset($_REQUEST['past'])) {
$result = mysqli_query($link, 'SELECT * FROM messages WHERE id > '.
mysqli_real_escape_string($link, $_REQUEST['past']).
' ORDER BY added LIMIT 50');
$messages = array();
echo json_encode($messages);
} else {
$result = mysqli_query($link, 'SELECT * FROM messages ORDER BY timeadded LIMIT 50');
$messages = array();
while ($row = mysqli_fetch_assoc($result)) {
$messages[] = $row;
}
echo json_encode($messages);
}
}
The output is like this:
[{"id":"1","user":"me","message":"my first message","timeadded":"2014-02-11 12:47:55"},{"id":"2","user":"me","message":"my second message","timeadded":"2014-02-18 14:29:23"}]
Here's my ViewController code:
h:
{
NSMutableData *responseData;
}
#property (nonatomic, strong) NSMutableArray *receivedData;
m:
#synthesize receivedData;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[responseData setLength:0];
NSLog(#"received response");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[responseData appendData:data];
NSLog(#"%#", receivedData);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Succeeded! Received %d bytes of data",[responseData length]);
receivedData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
NSLog(#"%#", responseData);
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self getNewMessages];
}
- (void)getNewMessages {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"messages.php?past=%d", lastId] relativeToURL:[NSURL URLWithString:#"http://www.mydomain.com/"]];
responseData = [NSMutableData dataWithCapacity:0];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"GET"];
NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if (conn)
{
receivedData = [[NSMutableArray alloc]init];
NSLog(#"sent request to server");
}
}
I'm just trying to log the array after it gets deserialized but it comes up empty in the log. The first two logs get displayed and then just (). What am I doing wrong here? The app builds and runs just fine, no errors...thanks in advance!
If I add a NSMutableData variable and try to do it like in the documentation, the data I get in the didReceiveData function look like this: <5b5d>. What does that mean?
Here's my response received:
{ status code: 200, headers {
Connection = "Keep-Alive";
"Content-Type" = "text/html";
Date = "Wed, 19 Feb 2014 00:03:30 GMT";
"Keep-Alive" = "timeout=10, max=30";
Server = Apache;
"Transfer-Encoding" = Identity;
Vary = "Accept-Encoding";
} }
ANSWER: So apparently the PHP script was wrong...it didn't like isset. Once I got rid of that, I got my data to return. Following the iOS documentation, everything worked like it should.
You're not using connection:didReceiveData: correctly. You should create an NSMutableData instance, and append the data received in connection:didReceiveData: to it. You should do the conversion to your array in connectionDidFinishLoading: which you haven't implemented. Look at the code Apple shows in the "URL Loading System Programming Guide" for an example.
Please refer the document for your reference from this link. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the new data to the instance variable you declared
[_responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
NSLog(#"%#", [NSJSONSerialization JSONObjectWithData:_responseData options:kNilOptions error:nil]);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// The request has failed for some reason!
// Check the error var
}
in my Program, I have a NSMutableData variable that collect the information from http://www.nhara.org/scored_races-2013.htm. After about the third time it gets information from a website, when it contains 90810 bytes, it either disappears or becomes null because if I print it a NSString, it is null. Here is the code
- (void)viewWillAppear:(BOOL)animated
{
// Create a new data container for the stuff that comes back from the service
xmlData = [[NSMutableData alloc] initWithCapacity:180000];
[self fetchEntries];
[super viewWillAppear:animated];
}
- (void)fetchEntries
{
// Construct a URL that will ask the service for what you want
NSURL *url = [NSURL URLWithString: #"http://www.nhara.org/scored_races-2013.htm"];//
// Put that URL into an NSURLRequest
NSURLRequest *req = [NSURLRequest requestWithURL:url];
// Create a connection that will exchange this request for data from the URL
connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
}
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
// Add the incoming chunk of data to the container we are keeping
// The data always comes in the correct order
[xmlData appendData:data];
NSLog(#"%#",xmlData);
NSString *xmlCheck = [[[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding]autorelease];
NSLog(#"xmlCheck = %#", xmlCheck);
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"error= %#",error);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)conn {
// We are just checking to make sure we are getting the XML
NSString *xmlCheck = [[[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding] autorelease];
NSLog(#"xmlCheck2 = %#", xmlCheck);
}
What confuses me the most is that my NSMutableData stores data, but then loses it while claiming to have the same number of bytes.
Is there a constraint to the NSMutableData's size or is my problem just memory management?
You need to create a property for your xmlData variable. In your header file after your
#interface MyClass, make one like so
#property (nonatomic, retain) NSMutableData * xmlData;
If you are using ARC you leave it as strong if you using below ARC you change strong to retain. When you want to use your variable you do self.xmlData