iOS:Загрузите изображение с URL-адреса и сохраните на устройстве

StackOverflow https://stackoverflow.com/questions/2499176

Вопрос

Я пытаюсь загрузить изображение с URL-адреса http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg

Я использую следующий код, но изображение не сохраняется на устройстве.Я хочу знать, что я делаю не так.

 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];
Это было полезно?

Решение

Если вы установите theData Для nil, что, по-вашему, он должен записать на диск?

То, что вы можете использовать, это NSData* theData = [NSData dataWithContentsOfURL:yourURLHere]; чтобы загрузить данные с диска, а затем сохранить их с помощью writeToFile:atomically:.Если вам нужно больше контролировать процесс загрузки или выполнять его в фоновом режиме, ознакомьтесь с документацией NSURLConnection и связанное с ним руководство.

Другие советы

Так случилось, что у меня есть именно то, что вы ищете.

Получить изображение С URL

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

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

    return result;
}

Сохранить изображение

-(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);
    }
}

Загрузить изображение

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

    return result;
}

Как-К

//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];

Это код для загрузки изображения с URL-адреса и сохранения этого изображения на устройстве и это является ссылочной ссылкой.

 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];

Получить изображение С URL

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

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

    return result;
}

Это отлично сработало для меня, но я столкнулся с проблемами с памятью с CFData (store).Исправил это с помощью autoreleasepool:

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

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

     return result;
    }
 }

Поскольку сейчас мы работаем на IOS6, вам больше не нужно обязательно записывать изображения на диск.
Начиная с iOS5, теперь вы можете установить "разрешить внешнее хранилище" для двоичного атрибута coredata.Согласно примечаниям к выпуску apple, это означает следующее:

Небольшие значения данных, такие как миниатюры изображений, могут эффективно храниться в базе данных, но большие фотографии или другие носители лучше всего обрабатывать напрямую файловой системой.Теперь вы можете указать, что значение управляемого атрибута объекта может храниться как внешняя запись - см. setAllowsExternalBinaryDataStorage Хранилище: При включении сердечник сведения эвристически решает на основе, если значение она должна сохранять данные непосредственно в базе данных или хранить URI в отдельный файл, который управляет для вас.Вы не сможете выполнять запросы на основе содержимого свойства двоичных данных, если вы используете эту опцию.

Привет, Очевидно, что вы записываете нулевые данные в свой файл.

В вашем операторе кода NSData *thedata = NULL;указывает, что вы присваиваете своим данным нулевое значение.

Вы также записываете нулевые данные в свой файл.

Пожалуйста, проверьте свой код еще раз.

-(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];    
}

Вот как вы можете асинхронно сохранить изображение в Swift:

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)
            }
    })
}

Он включен в качестве стандартной функции в мое репо:

https://github.com/goktugyil/EZSwiftExtensions

Вот пример того, как я загружаю баннеры в свое приложение.Я загружаю изображения в фоновом режиме, и большинство моих приложений не используют подсчет ссылок, поэтому я освобождаю объекты.

- (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];
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top