2011-10-06 89 views
1

我有一些代碼將檢查如果圖像是在手機上還是沒有(這個名字從數據庫被檢索),如果不是,它運行這段代碼:iPhone圖片保存從網絡發出

NSString *urlString = [NSString stringWithFormat: @"http://www.vegashipster.com/%@",image_path];       
NSData *imageData = [[NSData alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]]]; 

NSLog(@"saving jpg"); 
UIImage *image = [[UIImage alloc] initWithData:imageData];//1.0f = 100% quality 

[UIImageJPEGRepresentation(image, 1.0f) writeToFile:myFilePath atomically:YES]; 
NSLog(@"saving image done"); 
NSLog(@"URL String: %@",urlString); 
NSLog(@"http://www.vegashipster.com/%@",image_path); 

rest_image = [UIImage imageNamed:image_path]; 

[image release]; 
[imageData release]; 

這段代碼在模擬器上工作得很好,但在iPhone上,屏幕凍結了幾秒鐘(下載圖像,我認爲),然後加載頁面,但沒有可見的圖像。下一次你點擊那個頁面時,沒有凍結。所以我相信該文件正在創建,但它是一個混亂的圖像文件,因此不顯示。

我已經打破了這個代碼,使它運行在它自己的線程中,並且它再次運行在模擬器中。我曾經想過,如果它在幕後運行,圖像數據會變得混亂的可能性會降低,但同樣的事情會發生(減去凍結)。有誰知道我在做什麼這個代碼錯了?感謝您的任何幫助/意見。

編輯

是的,被下載的圖像都嚴格.JPG

編輯2

我看到:

確保你正在寫作g到您的DOCUMENTS目錄,您已經讀取了+寫入權限。否則你不會得到任何文件。

at http://www.iphonedevsdk.com/forum/iphone-sdk-development/15628-file-weirdness-files-written-disk-do-not-appear-nsfilemanager-defaultmanager.html。這可能是我的問題嗎?

NSString *image_path = [[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 5)] stringByReplacingOccurrencesOfString:@"../" 
NSString *myFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:image_path]; 

最後編輯

嗯,我找到了我認爲是我在How can I get a writable path on the iPhone?答案。它幾乎說明我無法將圖像文件保存在構建內的圖像文件所在的位置。如果這是不正確的,請讓我知道,我會嘗試你的方式。

+0

你修好了嗎?發生了什麼?我想我跑了相同的情況。 – Daniel

+0

@丹尼爾我做到了。我只是在下面發佈我的代碼。 – James

回答

0

對不起,忘了這個線程完全。我確實最終解決了這個問題。這是我做的:

NSFileManager* fileManager = [NSFileManager defaultManager]; 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); 
NSString *libraryDirectory = [paths objectAtIndex:0]; 

NSString *myFilePath = [libraryDirectory stringByAppendingPathComponent:image_path]; 

BOOL fileExists = [fileManager fileExistsAtPath:myFilePath]; 

if (fileExists){ 
    hotel_image = [UIImage imageWithContentsOfFile:myFilePath]; 
}else{ 
    [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:[HotelsDetailsViewController class] withObject:image_path]; 

    fileExists = [fileManager fileExistsAtPath:myFilePath]; 

    if (fileExists){ 
     hotel_image = [UIImage imageWithContentsOfFile:myFilePath]; 
    }else{ 
     hotel_image = [UIImage imageNamed:@"hdrHotels.jpg"]; 
    } 
} 

總之,我找到了我應用的庫目錄並保存在那裏。

1
NSData *imageData = [[NSData alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]]]; 

是一個同步調用,即它會阻止,直到它已完全執行,這在網絡運營的情況下,可以是1秒,10秒或3分鐘,如果你沒有時間了。你大概在主線程中運行這個,這就是爲什麼你的UI凍結的原因(所有UI的東西都在主線程上完成,所以你必須盡一切努力阻止它)。它不會下一次凍結的原因可能是它已經緩存了圖像數據。

你應該使用異步API,NSURLConnection有一些,但是我強烈建議ASIHTTPRequest,這是一個圍繞NSURLConnection和co的obj c包裝。代碼看起來像這樣(通過閱讀如何使用部分)

- (IBAction)grabURLInBackground:(id)sender 
{ 
    NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"]; 
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; 
    [request setDelegate:self]; 
    [request startAsynchronous]; 
} 

- (void)requestFinished:(ASIHTTPRequest *)request 
{ 
    // Use when fetching text data 
    NSString *responseString = [request responseString]; 

    // Use when fetching binary data 
    NSData *responseData = [request responseData]; 
    UIImage* downloadedImage = [UIImage imageWithData:responseData]; 
} 

- (void)requestFailed:(ASIHTTPRequest *)request 
{ 
    NSError *error = [request error]; 
} 
+0

對,我明白爲什麼它凍結等,但我不明白爲什麼圖像不會顯示完成後,就像模擬器一樣。我已經重寫了它,以便它在它自己的線程中,但是我希望在將它實現到另一個線程中以確保它正在工作之前,它可以像這樣解決。但我讚賞評論。 – James

+0

我不確定,但它可能是UIImage的事情應該在主線程(作爲一般規則UI ==主線程)完成,抱歉我誤讀沒有意識到你已經產卵了後臺線程。回調技術的優點是下載是在後臺完成的,但回調是在啓動它的同一個線程上完成的(這裏應該是主線程)。 – jbat100

+0

即使所有在主線程中,圖像都不顯示。就好像圖像下載失敗或文件被損壞或類似。但我不確定是什麼,或者爲什麼。正如我所說,這在模擬器上工作得很好,所以我不知道我是否告訴它保存錯誤或什麼。 – James