Подтвердить что ты не робот

Использование UIDocumentInteractionController для отображения presentPreviewAnimated: через UIWebView

Я хотел бы перехватить клики с любого из поддерживаемых типов файлов UIDocumentInteractionController и отобразить их в виде модальности (при условии по presentPreviewAnimated: методу UIDocumentInteractionController). Это модальное представление также предоставляет функцию "Открыть в...", чтобы открыть любой из этих документов в других совместимых приложениях на устройстве. Приведенный ниже код перехватит эти клики, определит, имеет ли строка URL какой-либо из соответствующих суффиксов, загружает эти данные, записывает их в каталог, читает их снова и, наконец, использует данные с помощью метода presentPreviewAnimated:. Я должен сначала записать данные в файловую систему, потому что UIDocumentInteractionController требует локальные данные и не может использовать данные непосредственно из URL (насколько я читал).

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
 if (navigationType == UIWebViewNavigationTypeLinkClicked) {
  ILog(@"URL loading for NavigationTypeLinkClicked: %@", request.URL.absoluteString);

  if ([request.URL.absoluteString hasSuffix:@"pdf"] || [request.URL.absoluteString hasSuffix:@"doc"] || [request.URL.absoluteString hasSuffix:@"xls"] || [request.URL.absoluteString hasSuffix:@"ppt"] || [request.URL.absoluteString hasSuffix:@"rtf"] || [request.URL.absoluteString hasSuffix:@"key"] || [request.URL.absoluteString hasSuffix:@"numbers"] || [request.URL.absoluteString hasSuffix:@"pages"]) {
   if (NSClassFromString(@"UIDocumentInteractionController")) {
                NSArray *parts = [request.URL.absoluteString componentsSeparatedByString:@"/"];
                self.previewDocumentFileName = [parts lastObject];
                NSLog(@"The file name is %@", previewDocumentFileName);

    // Get file online
                NSData *fileOnline = [[NSData alloc] initWithContentsOfURL:request.URL];

    // Write file to the Documents directory
                NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
                NSString *documentsDirectory = [paths objectAtIndex:0];
                if (!documentsDirectory) {NSLog(@"Documents directory not found!");}
                NSString *appFile = [documentsDirectory stringByAppendingPathComponent:previewDocumentFileName];
                [fileOnline writeToFile:appFile atomically:YES];
    NSLog(@"Resource file '%@' has been written to the Documents directory from online", previewDocumentFileName);
    [fileOnline release];

    // Get file again from Documents directory
                NSURL *fileURL = [NSURL fileURLWithPath:appFile];

    UIDocumentInteractionController* docController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];

    docController.delegate = self;
    [docController retain];

    BOOL result = [docController presentPreviewAnimated:YES];

    if (!result) {
     [docController release];
    }
    return NO;
   }
  }
 }

 // Do lots of other URL-detecting stuff here
}

Я также применяю следующие методы делегата для использования соответствующего представления и для удаления файла после отклонения представления (previewDocumentFileName - переменная класса):

#pragma mark -
#pragma mark Document Interaction Controller Delegate Methods

- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller {
 return self;
}

- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller {
 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *appFile = [documentsDirectory stringByAppendingPathComponent:previewDocumentFileName];
 NSFileManager *fileManager = [NSFileManager defaultManager];
 [fileManager removeItemAtPath:appFile error:NULL];
 //[controller release]; // Release here was causing crashes
}

Обратите внимание, что в Apple Documentation упоминалось о том, что контроллер документа необходимо сохранить вручную, поэтому я сделал это. Я также должен быть выпущен, поэтому я делаю это, если контроллер не был использован (верхний метод) и попытался выпустить его после его использования (метод делегирования), но этот выпуск вызывал сбои, поэтому я удалил его, и все кажется чтобы работать с этой точки зрения.

В связи с этим мой вопрос связан с тем, что, хотя этот код работает в симуляторе iPhone (онлайн-документ отображается правильно в представлении presentPreviewAnimated:, хотя без "Open In"...", который нельзя использовать в симе), он не показывает presentPreviewMethod: на iPad sim или моих реальных устройствах iPhone или iPad. Я считаю, что метод вызывается правильно, но метод presentPreviewAnimated: возвращает NO, что означает, что он не смог отобразить предварительный просмотр документа.

Зачем это было? Я не сохраняю файл должным образом (и, следовательно, он не обнаруживается как * pdf или * doc и т.д.)? Что еще я мог делать неправильно? Существует очень мало документации или пример кода, кроме Apple Documentation, поэтому я надеюсь, что по крайней мере этот код будет полезен кому-то, хотя я бы хотел, чтобы он работал на 100% первым. Спасибо заранее.

4b9b3361

Ответ 1

Игнорируя тот факт, что вы [docController retain] и [controller release] - я рекомендую попробовать [docController autorelease]. Там есть шанс, что он попытается сделать что-то сразу после вашего возвращения, но не позже во время исполнения. Если это произойдет, вы хотите освободить контроллер чуть позже, для чего нужен autorelease. Если он все еще сбой, вы не являетесь владельцем объекта. Хотя, если вы retain ing, вы отвечаете за release за его использование. После того, как вы выполнили автореализацию, установите его на nil, чтобы вы не пытались снова коснуться его.

Ответ 2

в методе dealloc вы просто пишете

- (void)dealloc {
 [controller release];
 controller = nil;
 [super dealloc];
}

Думаю, что это сработает ура!