-1

I am using below piece of code to download PDF from a URL, But i am getting following output along with a notices and errors.

My AppDelegate.h

@interface FileDownload2AppDelegate : UIResponder <UIApplicationDelegate , NSURLConnectionDataDelegate>
{
        NSMutableData *receivedData;
}

@property (strong, nonatomic) UIWindow *window;

@end

My AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        // Override point for customization after application launch.

        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://code.google.com/p/androidnetworktester/downloads/detail?name=1mb.txt"]];
        [NSURLConnection connectionWithRequest:request delegate:self];

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"/Users/awsuser8/1.txt"];
        NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://code.google.com/p/androidnetworktester/downloads/detail?name=1mb.txt"]];
        [thedata writeToFile:localFilePath atomically:YES];

        NSLog(@"PDF downloaded");

        return YES;
    }



- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    // This method is called when the server has determined that it
    // has enough information to create the NSURLResponse.

    // It can be called multiple times, for example in the case of a
    // redirect, so each time we reset the data.

    // receivedData is an instance variable declared elsewhere.
    [receivedData setLength:0];
}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [receivedData setData:data];

    [receivedData appendData:data];
    NSLog(@"receivedData : %@", receivedData);
}

- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error
{
    // release the connection, and the data object
    //[connection release];
    // receivedData is declared as a method instance elsewhere
    //[receivedData release];

    // inform the user
    NSLog(@"Connection failed! Error - %@ %@",
          [error localizedDescription],
          [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // do something with the data
    // receivedData is declared as a method instance elsewhere
    NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);

    // release the connection, and the data object
   // [connection release];
   // [receivedData release];
}

getting output:

lockdownd[53] <Notice>: 00281000 __copy_itunes_value_block_invoke: com.apple.mobile.iTunes.store/downloaded-apps -> (null)
lockdownd[53] <Notice>: 01a63000 __copy_itunes_value_block_invoke: com.apple.mobile.iTunes.store/downloaded-apps -> (null)
networkd[79] <Warning>: Analytics Engine: double ON for app: com.aasare.FileDownload2
backboardd[28] <Error>: HID: The 'Passive' connection 'FileDownload2' access to protected services is denied.
PDF downloaded
receivedData : (null)
receivedData : (null)
Succeeded! Received 0 bytes of data
svrushal
  • 1,612
  • 14
  • 25
  • In the method 'didReceiveData' you are using both set and appendData. Use appendData only and check – user2071152 Apr 21 '14 at 07:02
  • @user2071152 tried but getting same output – user3497411 Apr 21 '14 at 07:04
  • Is there any authentication required to download the data? As we can observe the error 'backboardd[28] : HID: The 'Passive' connection 'FileDownload2' access to protected services is denied.'. If so you can use 'didReceiveAuthenticationChallenge' method to provide the credentials. – user2071152 Apr 21 '14 at 07:10
  • Does this error message cause any issues? I never saw it before, but I just checked. This error appears for all my apps. Some of them are live in the app store, deployed to thousands of devices. This error appears on builds that are from the App Store. I use crashlytics for crash reporting. Currently I don't see any problems related to this error. Might be save to ignore it for now. – Matthias Bauch Apr 21 '14 at 07:42

2 Answers2

0

You should probably instantiate receivedData somewhere.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    receivedData = [NSMutableData data];
}

and you should append the received data.

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [receivedData appendData:data];
}

and you are downloading the file twice, but you discard the second download completely.

This code block downloads and saves the data already:

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://code.google.com/p/androidnetworktester/downloads/detail?name=1mb.txt"]];
    [NSURLConnection connectionWithRequest:request delegate:self];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"/Users/awsuser8/1.txt"];
    NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://code.google.com/p/androidnetworktester/downloads/detail?name=1mb.txt"]];
    [thedata writeToFile:localFilePath atomically:YES];

This happens in a synchronous way on the main thread. During the download the app does nothing else. If your download is large, or you have a slow connection your app might be terminated before it is even started.

Don't do this. Put the file saving code into the connectionDidFinishLoading:. This is the asynchronous way for handling network request. And that is how you should handle everything related to the network.

Additionally, the file you want to write to does not exist. writeData: does not create directorys. You probably should remove the whole /Users... path components. Or create it yourself.

e.g.:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://code.google.com/p/androidnetworktester/downloads/detail?name=1mb.txt"]];
    [NSURLConnection connectionWithRequest:request delegate:self];
    return YES;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    receivedData = [NSMutableData data];
}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [receivedData appendData:data];
}

- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error {
    NSLog(@"Connection failed! Error - %@ %@",
          [error localizedDescription],
          [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *directoyPath = [documentsDirectory stringByAppendingPathComponent:@"Users/awsuser8"];
    NSError *error;
    if (![[NSFileManager defaultManager] fileExistsAtPath:directoyPath]) {
        if (![[NSFileManager defaultManager] createDirectoryAtPath:directoyPath withIntermediateDirectories:YES attributes:nil error:&error]) {
            NSLog(@"Can't create directoy %@", error);
        }
    }
    NSString *localFilePath = [directoyPath stringByAppendingPathComponent:@"1.txt"];
    if (![receivedData writeToFile:localFilePath options:NSDataWritingAtomic error:&error]) {
        NSLog(@"Can't write file. %@", error);
    }
}
Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
  • How to get rid of this error : HID: The 'Passive' connection 'FileDownload2' access to protected services is denied. – user3497411 Apr 21 '14 at 07:25
-1

try to change into didReceiveData as bellow:

if(!receivedData)
    [receivedData setData:data];
else
   [receivedData appendData:data];
lee
  • 7,955
  • 8
  • 44
  • 60
  • 1
    I didn't downvote, but if you set `receivedData = nil` your code comes down to `[nil setData:data];`. Kind of useless. – Matthias Bauch Apr 21 '14 at 07:30
  • 1
    ok, I see.if the answer is wrong or not useful, down vote is right.But I just want to know the reason to improve myself.Thanks – lee Apr 21 '14 at 07:43