I need to download this video http://studiokicks.com/xtr/basic/1.mov The video is not getting downloaded when I use the following code:
NSURL *requestURL = [NSURL URLWithString:itemURL];
NSURLRequest *request = [NSURLRequest requestWithURL:requestURL];
NSData *data = [NSData dataWithContentsOfURL:requestURL];
NSLog(#"data - %d",[data length]);
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"didReceiveResponse");
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if ((([httpResponse statusCode]/100) == 2)) {
returnData = [NSMutableData data];
}
else
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject: NSLocalizedString(#"HTTP Error", #"Error message displayed when receving a connection error.")forKey:NSLocalizedDescriptionKey];
NSError *error = [NSError errorWithDomain:#"HTTP" code:[httpResponse statusCode] userInfo:userInfo];
NSLog(#"%#",error);
}
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[returnData appendData:data];
// Build an array from the dictionary for easy access to each entry
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection1
{
NSString *filePath = [VIDEOPATH stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.mov",videoName]];
BOOL success = [returnData writeToFile:filePath atomically:YES];
NSLog(#"successfully saved - %d",success);
}
You need to set a member self.data of type NSMutableData.
Before starting loading the NSURLConnection, initialize: self.data = [NSMutableData new].
In the connectionDidReceiveData method do: [self.data appendData:data].
And in the connectionDidFinishLoading you can view the data.
Related
I am using this code to load data to my App, can you tell me how can I make this asynchronously?
NSMutableURLRequest *request2 = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request2 delegate:self];
if (connection)
{
NSLog(#"NSURLConnection connection==true");
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request2 returningResponse:&response error:&err];
self.news =[NSJSONSerialization JSONObjectWithData:responseData options:nil error:nil];
NSLog(#"responseData: %#", self.news);
}
else
{
NSLog(#"NSURLConnection connection==false");
};
I think you should be bothered reading the documentation. There's a sendAsynchronousRequest:queue:completionHandler: method.
Create the connection with initWithRequest:delegate:startImmediately:, set yourself as its delegate and implement the delegate methods.
Block code is your friend. I have created a class which does this for you
Objective-C Block code. Create this class here
Interface class
#import <Foundation/Foundation.h>
#import "WebCall.h"
#interface WebCall : NSObject
{
void(^webCallDidFinish)(NSString *response);
}
#property (nonatomic, retain) NSMutableData *responseData;
-(void)setWebCallDidFinish:(void (^)(NSString *))wcdf;
-(void)webServiceCall :(NSString *)sURL_p : (NSMutableArray *)valueList_p : (NSMutableArray *)keyList_p;
#end
Implementation class
#import "WebCall.h"
#import "AppDelegate.h"
#implementation WebCall
#synthesize responseData;
-(void)setWebCallDidFinish:(void (^)(NSString *))wcdf
{
webCallDidFinish = [wcdf copy];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
int responseStatusCode = [httpResponse statusCode];
NSLog(#"Response Code = %i", responseStatusCode);
if(responseStatusCode < 200 || responseStatusCode > 300)
{
webCallDidFinish(#"failure");
}
[responseData setLength:0];
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"WebCall Error: %#", error);
webCallDidFinish(#"failure");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
response = [response stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
webCallDidFinish(response);
}
-(void)webServiceCall :(NSString *)sURL_p : (NSMutableArray *)valueList_p : (NSMutableArray *)keyList_p
{
NSMutableString *sPost = [[NSMutableString alloc] init];
//If any variables need passed in - append them to the POST
//E.g. if keyList object is username and valueList object is adam will append like
//http://test.jsp?username=adam
if([valueList_p count] > 0)
{
for(int i = 0; i < [valueList_p count]; i++)
{
if(i == 0)
{
[sPost appendFormat:#"%#=%#", [valueList_p objectAtIndex:i],[keyList_p objectAtIndex:i]];
}
else
{
[sPost appendFormat:#"&%#=%#", [valueList_p objectAtIndex:i], [keyList_p objectAtIndex:i]];
}
}
}
NSData * postData = [sPost dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
NSString * postLength = [NSString stringWithFormat:#"%d",[postData length]];
NSURL * url = [NSURL URLWithString:sURL_p];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
if (theConnection)
{
self.responseData = [NSMutableData data];
}
}
#end
Then you to make this web call, you call it like this
WebCall *webCall = [[WebCall alloc] init];
[webCall setWebCallDidFinish:^(NSString *response){
//This method is called as as soon as the web call is finished
NSString *trimmedString = [response stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if([trimmedString rangeOfString:#"failure"].location == NSNotFound)
{
//Successful web call
}
else
{
//If the webcall failed due to an error
}
}];
//Make web call here
[webCall webServiceCall:#"http://www.bbc.co.uk/" :nil :nil];
See the setWebCallDidFinish method, it will not be called until the webcall has finished.
Hope that helps!!
Here is some code which I am using in my app:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:yourURL]];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error) {
NSLog(#"Error loading data from %#. Error Userinfo: %#",yourURL, [error userInfo]);
} else {
NSDictionary *dataFromServer = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
contentAsString = [[[dataFromServer objectForKey:#"page"] objectForKey:#"content"] stripHtml];
completionHandler(contentAsString);
}];
fyi: stripHTML is a NSString Category to remove HTML tags from JSON --> Found it Here
you can call your content in your class like that:
[yourClass getDataWithcompletionHandler:^(NSString *content) {
yourObject.content = content;
[yourClass saveManagedObjectContext];
}];
if you implement it once, you won't want to use synchronous connection again...
Check this out: HTTPCachedController
It will help you send POST and GET requests, while it will cache the response and after that it will return the cached data when no internet connection is available.
HTTPCachedController *ctrl = [[[HTTPCachedController alloc] initWithRequestType:1 andDelegate:self] autorelease];
[ctrl getRequestToURL:#"https://api.github.com/orgs/twitter/repos?page=1&per_page=10"];
You will get notified when the data are fetched through a delegate method:
-(void)connectionFinishedWithData:(NSString*)data andRequestType:(int)reqType
I want to access a URL and retrieve data from this URL, based on the data retrieved I want to retrieve data from another URL
I tried accessing multiple URL in the following way:
- (void) showClassRoom:(NSString *)theMessage{
NSString *queryURL =[NSString stringWithFormat:#"http://nobert.cloudfoundry.com/CalOfEvents/tos"];
NSURL *url = [NSURL URLWithString: queryURL];
NSURLRequest *req = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSError *error;
NSURLResponse *response;
NSData *returnData = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
if(returnData){
NSString *strResult = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
NSDictionary *result = [strResult JSONValue];
for(id theKey in result){
for(id hello in theKey){
NSLog(#"The key:%#, The value:%#",hello,[theKey objectForKey:hello]);
}
}
if(TRUE){//based on some condition secondShowClassRoom is called
[self secondShowClassRoom];
}
}
}
- (void) secondShowClassRoom{
NSString *queryURL =[NSString stringWithFormat:#"http://nobert.cloudfoundry.com/CalOfEvents/to"];
NSURL *url = [NSURL URLWithString: queryURL];
NSURLRequest *req = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSError *error;
NSURLResponse *response;
NSData *returnData = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
if(returnData){
NSString *strResult = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
NSDictionary *result = [strResult JSONValue];
for(id theKey in result){
for(id hello in theKey){
NSLog(#"The key:%#, The value:%#",hello,[theKey objectForKey:hello]);
}
}
}
}
This retrieves the data VERY SLOWLY and my app requires very fast access as I am developing an application on Augmented Reality
There is another method that is faster however I am not able to access multiple URLs:
- (void) showClassRoom:(NSString *)theMessage{
NSString *queryURL =[NSString stringWithFormat:#"http://nobert.cloudfoundry.com/CalOfEvents/to"];
NSURL *url = [NSURL URLWithString: queryURL];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (conn) {
webData = [[NSMutableData data] retain];
}
classRoomControl.hidden = NO;
labControl.hidden = YES;
placementControl.hidden = YES;
}
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *) response{
[webData setLength: 0]; }
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *) data {
[webData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *) error {
[conn release];
[webData release];
}
-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
[conn release];
NSLog(#"DONE. Received Bytes: %d", [webData length]);
NSString *strResult = [[NSString alloc] initWithBytes:[webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
NSDictionary *result = [strResult JSONValue];
for(id theKey in result){
for(id hello in theKey){
NSLog(#"The key:%#, The value:%#",h,hello);
}
}
[strResult release];
[webData release];
}
Please Help me with this.Any help would be appreciated..
You are right on track preferring the asynchronous model for network communication (since synchronous communication will block your UI unless you handle it in a separate thread).
The correct way to chain multiple asynchronous network request is doing one request after another in the callbacks (i.e., in connectionDidFinishLoading; when one request is done, you send the next one).
One more suggestion is not using NSURlRequest/NSURLConnection for that, since they make thinks unnecessarily complex, and try with a framework like AFNetworking.
I am trying to call a webservice but unfortunateley my calls are not recorded and I am not sure why it is doing so ...
here is the code that I am using , maybe I am missing something :
NSURL *URL = [NSURL URLWithString:#"http://www.google.com"];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:URL];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
all I need to do is to be able to load a web page without having to load it in safari nor in a web view
thanks!
Checkout this tutorial on how to connect with a webservice in iOS. It's not as simple as making the connection.
NSURL *url = [NSURL URLWithString:webService];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if(theConnection) {
//webData = [[NSMutableData data] retain];
}else {
NSLog(#"The Connection is NULL");
}
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
webData = [[NSMutableData data] retain];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
}
I am developing view based application.I have login page when we click on Login button it should check entered values with webserver values and it should display vali or invalid.I have wriiten code in this way it is executing successfully i am getting the result in this way
<!DOCTYPE html PUbLIC" -//W3C//DTD XHTML 1.0 Strict....
What i need to change in below code to comapre with server values..can any one help me regarding this please...
-(IBAction)buttonClick:(id)sender
{
NSString* username = nameInput.text;
NSString* pass = passInput.text;
if([nameInput.text isEqualToString:#"" ]|| [passInput.text isEqualToString:#""])
{
greeting.text = #"Input Your Value";
[nameInput resignFirstResponder];
[passInput resignFirstResponder];
return;
}
NSString *post =
[[NSString alloc] initWithFormat:#"uname=%#&pwd=%#",username,pass];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSURL *url = [NSURL URLWithString:#"https://108.16.210.28/Account/LogOn"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
[theRequest setHTTPMethod:#"POST"];
[theRequest setValue:postLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPBody:postData];
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection )
{
webData = [[NSMutableData data] retain];
}
else
{
}
[nameInput resignFirstResponder];
[passInput resignFirstResponder];
nameInput.text = nil;
passInput.text = nil;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webData setLength: 0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[connection release];
[webData release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *loginStatus = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
NSLog(loginStatus);
greeting.text = loginStatus;
[loginStatus release];
[connection release];
[webData release];
}
- (void)dealloc {
[super dealloc];
}
#end
Use statusCode to see the login state.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
if([response isKindOfClass:[NSHTTPURLResponse class]])
{
NSHTTPURLResponse *theResponse = (NSHTTPURLResponse*)response;
NSInteger theStatusCode = [theResponse statusCode];
}
}
you have to parse the data.If it is in the form of XML data then you have to parse the element (like valid) in the didfoundcharacters.If it is valid then make a variable like BOOL confirm = NO;Modify this in the didfoundcharacters.if (confirm) then give access further
In my application I want to use the NSURLConnection class. So please tell me how to use this one? This contain the lot of delegate methods, please tell me how to use them?
Initiate the connection using
self.responseData = [NSMutableData data];
NSURL *url = [NSURL URLWithString:#"http://sampleurl/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection autorelease];
and you can catch the response in the connectionDidFinishLoading delegate method
#pragma mark - NSURLConnection Delegate Methods
- (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 {
NSLog(#"Connection failed: %#", [error description]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//Getting your response string
NSString *responseString = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
self.responseData = nil;
}
For your memory leak problem
Declare the response data in interface file
NSMutableData *_responseData;
with property as below
#property (nonatomic, retain) NSMutableData *responseData;
and synthesize it
#synthesize responseData = _responseData;
Dont release it anywhere (We have used convenient constructors for allocation). We have already set it to nil in connectionDidFinishLoading method.
In iOS 5 and OS X 10.7 or later you can load data asynchronously using the following:
NSURL *url = [NSURL URLWithString:#"http://sampleurl/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue]
completionHandler: ^(NSURLResponse * response, NSData * data, NSError * error) {
NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse*)response;
if(httpResponse.statusCode == 200) {
//your code to handle the data
}
}
];
Or if you want to do it synchronously (not recommended if you are loading large data as it will hang the application) (available in OS X 10.2+ and iOS 2.0+)
NSURL *url = [NSURL URLWithString:#"http://sampleurl/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSURLResponse * response;
NSError * error;
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];