2013-08-12 2 views
2

서버에서 iPhone 앱 디렉토리 (문서 디렉토리)로 많은 (800-2000) 이미지를 저장하고 싶습니다.URL에서 iOS 디렉토리로 이미지 저장

먼저 이미지가 iPhone 디렉토리에 있는지 확인해야합니다.

내가 하나 개의 이미지 다운로드 코드를 사용

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

저를 도와주십시오, 어떤 제안 : 1. 저장 아이폰 디렉토리에 원래 이름, NOT "pkm.jpg" 2 모든 이미지. 이름이있는 이미지 저장 : 05052008321_bigger에서 05052008350_bigger 까지 3. 이미지가 이미 다운로드되었는지 확인하십시오. 다시 다운로드하지 마십시오.

아시다시피, 이것은 아마도 하나의 질문 일 것입니다. 그러나 몇 가지 제안, 방향 정말 좋을 것입니다.

미리 감사드립니다.

+0

보관 용 계정 또는 보관함을 사용할 수 있습니까? 그들은 이런 종류의 것들을위한 API를 내장하고 있습니까? –

+0

지금 확인 중입니다 ... 감사합니다. –

답변

2

반응의 몇 :

  1. 당신은 시작하고합니다 (NSURLConnectionDataDelegate 방법을 트리거),하지만 당신은 그때 분명히 그것을 무시하고 dataWithContentsOfURL을 시작 NSURLConnectionconnectionWithRequest. 둘 중 하나를 골라야하지만 둘 다하지는 마십시오.

  2. NSOperation 기반 솔루션을 사용하는 것이 좋습니다. 왜냐하면 확실히 (a) 동시성을 즐기기를 원하기 때문입니다. (b) 동시 작업을 적당한 수 (예 : 4 또는 5)로 제한하십시오. 그렇지 않으면 요청 시간이 초과되어 실패 할 수 있습니다.

  3. NSURL에서 lastPathComponent을 사용하여 파일 이름을 가져올 수 있습니다. (아래에 사용 된 내 다운로드 작업은 명시 적 파일 이름을 제공하지 않으면 실제로이 작업을 자동으로 사용합니다.)

  4. 원격 서버에서 파일 이름 목록을 결정하는 방법을 설명하지 않았으므로 어떤 이미지가 검색되는지 어떻게 알 수 있는지 알아야합니다.

  5. 이것은 자신의 목적이라면 괜찮습니다.하지만 Apple이 셀룰러 연결을 통해 너무 많은 데이터를 요청하는 응용 프로그램을 거부한다는 주장을 들었습니다. 솔직히 애플이 소란을 제기하지 않는 경우에도, 당신은 정말 자신의 데이터 계획의 대부분을 사용하기 전에 사용자에게 요구해야한다. 당신은 사용자가 무선 랜을 통해 또는 휴대 전화를 통해 연결되어 있는지 여부를 확인하기 위해 Reachability을 사용할 수 있으며, 후자의 경우에는 경고를 제시 할 수 있습니다.

하지만처럼 보이는 무언가를 건의 할 것 (에 당신이 URL의이 ... 분명히 URL 목록을 형성 무엇이든이를 조정의 NSString 버전으로 일부 NSArray이되어 가정) :

NSOperationQueue *downloadQueue = [[NSOperationQueue alloc] init]; 
downloadQueue.maxConcurrentOperationCount = 4; 
NSFileManager *fileManager = [NSFileManager defaultManager]; 
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 

for (NSString *urlString in urlStrings) 
{ 
    NSURL *url = [NSURL URLWithString:urlString]; 
    NSString *path = [docsPath stringByAppendingPathComponent:[url lastPathComponent]]; 
    if (![fileManager fileExistsAtPath:path]) { 
     DownloadOperation *downloadOperation = [[DownloadOperation alloc] initWithURL:url]; 
     downloadOperation.downloadCompletionBlock = ^(DownloadOperation *operation, BOOL success, NSError *error) { 
      if (error) NSLog(@"download of %@ failed: %@", operation.url, error); 
     }; 
     [downloadQueue addOperation:downloadOperation]; 
    } 
} 

그리고 다운로드 작업은 this 일 수 있습니다. 분명히 어떤 NSOperation 기반의 다운로더를 사용 하시겠지만, 전체 다운로드를 메모리에로드하지 않고 영구 저장 장치에 직접 스트리밍하는 것이 좋습니다. 당신이 공상을 얻을하지 않으려면

, 당신은 같은 것을 할 수있는 : 분명히

NSOperationQueue *downloadQueue = [[NSOperationQueue alloc] init]; 
downloadQueue.maxConcurrentOperationCount = 4; 
NSFileManager *fileManager = [NSFileManager defaultManager]; 
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 

for (NSString *urlString in urlStrings) 
{ 
    NSURL *url = [NSURL URLWithString:urlString]; 
    NSString *path = [docsPath stringByAppendingPathComponent:[url lastPathComponent]]; 
    if (![fileManager fileExistsAtPath:path]) { 
     [downloadQueue addOperationWithBlock:^{ 
      NSString *path = [docsPath stringByAppendingPathComponent:[url lastPathComponent]]; 
      NSData *data = [NSData dataWithContentsOfURL:url]; 
      if (data) 
       [data writeToFile:path atomically:YES]; 
     }]; 
    } 
} 

, 다운로드 작업 클래스를 사용하면 다운로드 할 원하는대로 사용을, 그러나 희망 당신은 기본 아이디어를 얻을. NSOperation 기반 다운로드를 만들고 다운로드해야하는 모든 파일에 대해 하나씩 제출하십시오.

1

정보를 직렬화하는 가장 좋은 방법은 확실하지 않습니다. 순진하게도 NSDictionary를 디스크에 쓸 수 있습니다. 큰 NSDictionary (작은 것들로, 최대 어떻게 할 수있는)로 나눌 수 있습니다. NSDictionary는 이미지 이름 "05052008321_bigger"를 취해이를 간단한 @YES에 매핑합니다.

앱이 새로운 이미지를 다운로드 할 수있는 위치에있을 때, (다른 스레드에서 읽을 수 있습니다) 디스크에서있는 NSDictionary를 읽을 것이며, 이미지 이름이 사전에 있는지 확인. 조회를 빠르게 할 수 있습니다.

- (BOOL)checkIfImageHasBeenDownloaded:(NSString *)imageName 
{ 
    return [self.dictionaryNames objectForKey:imageName] != nil; 
} 
관련 문제