2014-04-09 120 views
0

我正在研究使用核心數據的應用程序,並且所有內容都工作到目前爲止。但我還沒有使用過圖像。我想這樣做,但我不知道從哪裏開始。我想讓用戶點擊一個按鈕,讓他們選擇他們可以獲取圖像的位置。另外,是否有可能讓用戶輸入圖像的URL並將其保存到核心數據中?這真的是如此,如果有人能指出我在正確的方向,我將不勝感激。謝謝!單擊以將圖像添加到核心數據

我迄今爲止代碼:https://github.com/jackintosh7/Core-Data

回答

1

編輯 - 我更新了saveImgData:fromURL中的一些引用以匹配方法中傳遞的參數。我在NSURL協議中使用了該方法的一個變體來攔截請求並緩存特定的請求。一些實體參數可能不適用於您的問題。只要忽略這些(如encoding/lastModified/mimeType/response)。

要將圖像保存到CoreData,請嘗試一下。

首先,下載您的圖像。用戶可以在文本輸入字段中輸入URL。(由andrewbuilder列出的示例將工作得很好)

NSURL *imgURL = [NSURL URLWithString:myImgURL]; 
NSData *imgData = [NSData dataWithContentsOfURL:imgURL]; 

//a better way would be to do this asynchronously. Google "Lazy Image Loading" and 
//you should find a suitable example app from Apple 

設置您的CoreData實體以存儲圖像數據。這裏存儲的不僅僅是圖像二進制數據。

Entity Screen Shot

然後直接保存圖像數據到CoreData。 我有一個CoreData管理器類,但你可能在AppDelegate中有你的CoreData堆棧,這是Apple如何設置它們的。

-(void)saveImgData:(NSData*)myImgData fromURL:(NSString*)urlStr{ 

    //If you have a CoreData manager class do something like this 
    CoreDataManager *cdm = [CoreDataManager defaultManager]; 
    //Use private queue concurrency type for background saving 
    NSManagedObjectContext *ctx = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    //Set up the parent context, in this case is the mainMOC 
    //If you are using basic CoreData it would be the managedObjectContext on your AppDelegate 
    ctx.parentContext = cdm.mainMOC; 

    [ctx performBlock:^{ 
     //performBlock executes on a background thread 
     CachedURLResponse *cacheResponse = [NSEntityDescription insertNewObjectForEntityForName:@"CachedURLResponse" inManagedObjectContext:ctx]; 
     cacheResponse.relativeURLHash = [NSNumber numberWithInteger:[urlStr hash]]; 
     cacheResponse.data = [myImgData copy]; 
     cacheResponse.response = [NSKeyedArchiver archivedDataWithRootObject:self.response]; 
     cacheResponse.url = [urlStr copy]; 
     cacheResponse.timestamp = [NSDate date]; 
     cacheResponse.mimeType = [self.response.MIMEType copy]; 
     cacheResponse.encoding = [self.response.textEncodingName copy]; 
     if ([self.headers objectForKey:@"Last-Modified"]) 
      cacheResponse.lastModified = [self.headers objectForKey:@"Last-Modified"]; 

     NSError *__block error; 
     if (![ctx save:&error]) 
      NSLog(@"Error, Cache not saved: %@", error.userInfo); 

     [cdm.mainMOC performBlockAndWait: ^{ 
      [cdm saveContext]; 
     }]; 

    }]; 
} 

我CoreDataManager.h看起來是這樣的: CoreDataManager.h

和我CoreDataManager.m文件看起來像這樣:

#import "CoreDataManager.h" 
#import <CoreData/CoreData.h> 
@implementation CoreDataManager 

@synthesize mainMOC = _mainMOC, 
     managedObjectModel = _mom, 
     persistentStoreCoordinator = _psc 
; 


+(CoreDataManager*)defaultManager 
{ 
    static CoreDataManager *_defaultMgr = nil; 

     static dispatch_once_t oncePred; 
     dispatch_once(&oncePred, ^{ 
      _defaultMgr = [[CoreDataManager alloc] init]; 
     }); 

    return _defaultMgr; 

} 



-(id)init 
{ 
    if (self = [super init]) 
    { 
     NSError *error = nil; 
     NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyDatabase.sqlite"]; 
     NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyDataModelName" withExtension:@"momd"]; 

     _mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 
     _psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
     if (![_psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 

     _mainMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
     [_mainMOC setPersistentStoreCoordinator:self.persistentStoreCoordinator]; 

    } 
    return self; 
} 


- (void)saveContext 
{ 
    NSError *error = nil; 
    if (self.mainMOC != nil && ([self.mainMOC hasChanges] && ![self.mainMOC save:&error])) { 
     NSLog(@"CoreData save error: %@, %@", error, [error userInfo]); 
    } 
} 


#pragma mark - Core Data Stack 

- (NSManagedObjectContext *)mainMOC 
{ 
    return _mainMOC; 
} 

- (NSManagedObjectModel *)managedObjectModel 
{ 
    return _mom; 
} 

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
    return _psc; 
} 

- (NSURL *)applicationDocumentsDirectory 
{ 
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 
} 




@end 

希望給你一個很好的起點。谷歌的「CoreData類參考」爲這個主題提供了一些非常好的閱讀。

1

我學到了很多,從保羅赫加蒂的優秀的iTunes U /斯坦福統一講座......他最近被稱爲「Developing iOS Apps for iPhone and iPad」一對夫婦他的講座的具體處理圖像的使用中核心數據。對於你想要做的事情,我建議你看10-13講座,但真的值得看完整個系列。

除此之外,花一些時間閱讀核心數據的Apple文檔,從here開始。 Samir寫入一個很好的響應這個堆棧溢出question

您在執行代碼時有幾個選項。雖然Core Data能夠管理將圖像保存到持久性數據存儲(例如,sqlite)結構中,但重要的是要注意,大圖像文件會減慢獲取過程。

核心數據可以管理如何爲您存儲圖像...通過單擊數據模型檢查器中的允許外部存儲選項...請參閱下面的附加圖像。

Data Model Inspector for possible attribute pictureData

但是,如果你正在尋找一個用戶指向一個URL,它可能是值得考慮增加(另一個單獨的)屬性的實體Item,例如屬性命名pictureURL

使用在UIViewController物業管理實體屬性...

@property (nonatomic, retain) NSString * pictureURL;

然後你就可以添加一個UITextFieldUIViewController接受用戶輸入該物業pictureURL

當你有這個圖片的URL,你可以用類似這樣(其中UIImageUIViewController的屬性)「消氣」的代碼返回到圖像...

- (UIImage *)image { 
    NSURL *imageURL = [NSURL URLWithString:self.pictureURL]; 
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; 
    return [UIImage imageWithData:imageData]; 
} 

希望提供你有一些方向。

相關問題