web-dev-qa-db-de.com

iOS: Bild von der URL herunterladen und im Gerät speichern

Ich versuche, das Bild von der URL herunterzuladen http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg

Ich verwende den folgenden Code, aber das Bild wird nicht auf dem Gerät gespeichert. Ich möchte wissen, was ich falsch mache.

 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg"]];
 [NSURLConnection connectionWithRequest:request delegate:self];

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *documentsDirectory = [paths objectAtIndex:0];
 NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"pkm.jpg"];
 NSData *thedata = NULL;
 [thedata writeToFile:localFilePath atomically:YES];

 UIImage *img = [[UIImage alloc] initWithData:thedata];
44
User97693321

Wenn Sie theData auf nil setzen, was erwarten Sie von ihm auf die Festplatte?

Sie können NSData* theData = [NSData dataWithContentsOfURL:yourURLHere]; verwenden, um die Daten von der Festplatte zu laden und sie dann mit writeToFile:atomically: zu speichern. Wenn Sie mehr Kontrolle über den Ladevorgang benötigen oder sich im Hintergrund befinden, lesen Sie die Dokumentation zu NSURLConnection und das zugehörige Handbuch.

35
Alfonso

Ich habe genau das, wonach Sie suchen.

Bild von URL abrufen

-(UIImage *) getImageFromURL:(NSString *)fileURL {
    UIImage * result;

    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
    result = [UIImage imageWithData:data];

    return result;
}

Bild speichern

-(void) saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
    if ([[extension lowercaseString] isEqualToString:@"png"]) {
        [UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]] options:NSAtomicWrite error:nil];
    } else if ([[extension lowercaseString] isEqualToString:@"jpg"] || [[extension lowercaseString] isEqualToString:@"jpeg"]) {
        [UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]] options:NSAtomicWrite error:nil];
    } else {
        NSLog(@"Image Save Failed\nExtension: (%@) is not recognized, use (PNG/JPG)", extension);
    }
}

Bild laden

-(UIImage *) loadImage:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
    UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.%@", directoryPath, fileName, extension]];

    return result;
}

Wie man

//Definitions
NSString * documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

//Get Image From URL
UIImage * imageFromURL = [self getImageFromURL:@"http://www.yourdomain.com/yourImage.png"];

//Save Image to Directory
[self saveImage:imageFromURL withFileName:@"My Image" ofType:@"png" inDirectory:documentsDirectoryPath];

//Load Image From Directory
UIImage * imageFromWeb = [self loadImage:@"My Image" ofType:@"png" inDirectory:documentsDirectoryPath];
101

Dies ist der Code zum Herunterladen des Bildes von der URL und zum Speichern des Bildes im Gerät und das ist der Referenzlink.

 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg"]];
 [NSURLConnection connectionWithRequest:request delegate:self];

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *documentsDirectory = [paths objectAtIndex:0];
 NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"pkm.jpg"];
 NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg"]];
 [thedata writeToFile:localFilePath atomically:YES];
9
User97693321

Image von URL abrufen

-(UIImage *) getImageFromURL:(NSString *)fileURL {
    UIImage * result;

    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
    result = [UIImage imageWithData:data];

    return result;
}

Das funktionierte für mich sehr gut, aber ich hatte Probleme mit CFData (Speicher). Problem mit einem Autoreleasepool behoben:

 -(UIImage *) getImageFromURL:(NSString *)fileURL {
    @autoreleasepool {
     UIImage * result;

     NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
     result = [UIImage imageWithData:data];

     return result;
    }
 }
4
mark.ed
-(IBAction)BtnDwn:(id)sender
{
  [self.actvityIndicator startAnimating];

  NSURL *URL = [NSURL URLWithString:self.dataaArray];
  NSURLRequest *request = [NSURLRequest requestWithURL:URL];
  NSURLSession *session = [NSURLSession sharedSession];

  NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error)
   {

      NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
      NSURL *documentsDirectoryURL = [NSURL fileURLWithPath:documentsPath];
      NSURL *documentURL = [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
      BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:[documentURL path]];

      if (exists)
      {
         NSLog(@"not created");
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Download"
                                                    message:@"sory,file already exists"
                                                   delegate:nil
                                          cancelButtonTitle:@"cancel"
                                          otherButtonTitles:nil];
         [alert show];
      }
      else
      { 
         [[NSFileManager defaultManager] moveItemAtURL:location toURL:documentURL error:nil];
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Download"
                                                    message:@"Succesfully downloaded"
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
         [self.actvityIndicator stopAnimating];
         NSLog(@"wait downloading......");
         [alert show];
     }
  }];

    [downloadTask resume];    
}
2
Rahul Ranjan

Hallo, es ist klar, dass Sie NULL-Daten in Ihre Datei schreiben.

In Ihrer Code-Anweisung NSData * thedata = NULL; zeigt an, dass Sie Ihren Daten einen NULL-Wert zuweisen.

Sie schreiben auch NULL-Daten in Ihre Datei.

Bitte überprüfen Sie noch einmal Ihren Code.

2
Jim

Da wir jetzt auf IOS6 arbeiten, müssen Sie keine Images mehr auf die Festplatte schreiben.
Seit iOS5 können Sie jetzt "Erlaube externen Speicherplatz" für ein Coredata-Binärattribut festlegen.

Kleine Datenwerte wie Bildminiaturen können effizient in einem .__ gespeichert werden. Datenbank, aber große Fotos oder andere Medien werden am besten direkt von .__ verarbeitet. das Dateisystem. Sie können jetzt den Wert eines verwalteten .__ angeben. Objektattribut kann als externer Datensatz gespeichert werden - siehe setAllowsExternalBinaryDataStorage: Wenn diese Option aktiviert ist, entscheidet heuristisch für Core Data, ob Es sollte die Daten direkt in der Datenbank speichern oder einen URI in einer .__ speichern. separate Datei, die für Sie verwaltet wird. Sie können nicht basierend auf der .__-Abfrage abfragen. Inhalt einer binären Dateneigenschaft, wenn Sie diese Option verwenden.

2
Alexander

So können Sie ein Bild asynchron in Swift speichern:

requestImage("http://www.asdf.com/89asdf.gif") { (image) -> Void in
    let myImage = image
}

func requestImage(url: String, success: (UIImage?) -> Void) {
    requestURL(url, success: { (data) -> Void in
        if let d = data {
            success(UIImage(data: d))
        }
    })
}

func requestURL(url: String, success: (NSData?) -> Void, error: ((NSError) -> Void)? = nil) {
    NSURLConnection.sendAsynchronousRequest(
        NSURLRequest(URL: NSURL (string: url)!),
        queue: NSOperationQueue.mainQueue(),
        completionHandler: { response, data, err in
            if let e = err {
                error?(e)
            } else {
                success(data)
            }
    })
}

Es ist als Standardfunktion in meinem Repo enthalten:

https://github.com/goktugyil/EZSwiftExtensions

1
Esqarrouth

Hier ein Beispiel, wie ich Banner in meine App herunterlade. Ich lade die Bilder im Hintergrund herunter, und die meisten meiner Apps verwenden keine Referenzzählung.

- (void)viewDidLoad {
    [super viewDidLoad];

    [NSThread detachNewThreadSelector:@selector(loadImageInBackground) toTarget:self withObject:nil];

}

- (void) loadImageInBackground {
    NSURL *url = [[NSURL alloc] initWithString:@"http://yourImagePath.png"];
    NSData *data = [[NSData alloc] initWithContentsOfURL:url];
    [url release];
    UIImage *result = [[UIImage alloc] initWithData:data];
    [data release];

    UIImageView *banner_ImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
    [self.view addSubview:banner_ImageView];
    banner_ImageView.image = result;
    [result release];
}
0
Bobby