Отображение изображений в uiwebview из основной записи данных - PullRequest
0 голосов
/ 01 октября 2011

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

Я сохраняю изображение следующим образом:

NSManagedObjectContext* moc=[(ActionNote3AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSString* imageName=[NSString stringWithFormat:@"img%lf.png",[NSDate  timeIntervalSinceReferenceDate]];
Image* anImage = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:moc];
anImage.imageName=imageName;
anImage.imageData=UIImagePNGRepresentation(theImage);
NSError* error=nil;
if(![moc save:&error]) {...

Я подкласс NSURLCache, как предложено для Какао с любовью , и ovverride cachedResponseForRequest, таким образом:

- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
    NSString *pathString = [[[request URL] absoluteString]lastPathComponent];
    NSData* data = [Image dataForImage:pathString];
    if (!data) {
        return [super cachedResponseForRequest:request];
    }

    NSURLResponse *response =[[[NSURLResponse alloc] 
                               initWithURL:[request URL] 
                               MIMEType:[NSString stringWithString:@"image/png"] 
                               expectedContentLength:[data length] 
                               textEncodingName:nil] 
                              autorelease];
    NSCachedURLResponse* cachedResponse =[[[NSCachedURLResponse alloc] initWithResponse:response data:data] autorelease];

    return cachedResponse;
}

Я также убедился, что приложение использует субклассированный NSURLCache, выполнив это в моем делегате приложения в didFinishLaunchingWithOptions:

ANNSUrlCache* uCache=[[ANNSUrlCache alloc]init];
[NSURLCache setSharedURLCache:uCache];

Метод, который возвращает данные изображения из основной записи данных, выглядит следующим образом:

+(NSData*)dataForImage:(NSString *)name {
    NSData* retval=nil;
    NSManagedObjectContext* moc=[(ActionNote3AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Image" inManagedObjectContext:moc];
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"imageName==%@", name];
[request setPredicate:predicate];

    NSError* error=nil;
    NSArray *array = [moc executeFetchRequest:request error:&error];

    if ([array count]>0) {
        retval=((Image*)[array objectAtIndex:0]).imageData;
    }

    return retval;
}

Чтобы вставить изображение в веб-представление, у меня есть тег html img, где имя в src = "" относится к имени в таблице изображений.Смысл приведенного выше кода NSURLCache заключается в том, чтобы отслеживать имя, которое мы сохранили в таблице изображений, перехватывать его и отправлять фактические данные изображения для запрошенного изображения.

Когда я запускаю это, я вижу изображениеполучать запрос в моем подклассе NSURLCache объект.Он находит правильную запись и возвращает данные как следует.Тем не менее, я все еще получаю значок изображения не найден в моем uiwebview:

Image for Image Not Found

Так что Маркус (ниже) предложил мне не сохранять данные изображения в таблице основных данных.Поэтому я внес изменения, чтобы приспособиться для этого:

Сохранение изображения:

NSString* iName=[NSString stringWithFormat:@"img%lf.png",[NSDate timeIntervalSinceReferenceDate]];
NSData* iData=UIImagePNGRepresentation(theImage);

NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:iName];
[iData writeToFile:fullPathToFile atomically:NO];

Получение изображения:

- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
    NSString *pathString = [[[request URL] absoluteString]lastPathComponent];
    NSString* iPath = [Image pathForImage:pathString];
    if (!iPath) {
        return [super cachedResponseForRequest:request];
    }

    NSData* idata=[NSData dataWithContentsOfFile:iPath];

    NSURLResponse *response =[[[NSURLResponse alloc] 
                               initWithURL:[request URL] 
                               MIMEType:@"image/png" 
                               expectedContentLength:[idata length] 
                               textEncodingName:nil] 
                              autorelease];
    NSCachedURLResponse* cachedResponse =[[[NSCachedURLResponse alloc] initWithResponse:response data:idata] autorelease];

    return cachedResponse;
}

В режиме отладки я вижу, что idata делаетзагружаются с правильными данными изображения.

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

Итак ... Что я здесь не так делаю?Как я могу заставить это работать должным образом?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 05 октября 2011

Оказывается, я слишком обдумал это. Когда я пишу HTML, я просто пишу путь к изображению с тегом image. Работает как шарм.

Хотелось бы узнать, почему решение, поставленное мной в моем вопросе, не сработало.

И я не стал хранить изображения в таблице.

0 голосов
/ 03 октября 2011

Я бы настоятельно предположил, что вы не храните двоичные данные в Базовых данных. Хранение двоичных данных в Core Data, особенно на устройстве iOS, вызывает серьезные проблемы с производительностью кеша.

Предпочтительным способом было бы сохранить фактические двоичные данные на диске в файле и иметь ссылку на файл, хранящийся в Базовых данных. Оттуда просто изменить URL-адрес изображения так, чтобы он указывал на локальный файл.

...