Обработка приложения: openURL: sourceApplication: для открытия файлов в приложении iOS - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть приложение, которое использует некоторые известные большие форматы файлов и поддерживает функцию «Открыть в ...» в iOS со времен iOS4.

До недавнего времени все работало нормально, некоторые приложения, такие каквстроенное в iOS почтовое приложение для iOS откроет приложение, сделав копию в каталоге ~ / Documents / Inbox внутри моего приложения, и жизнь будет хорошей.

Недавно мне стало известно о том, что "Open In... "больше не работает для моего приложения, по крайней мере, когда файлы приходят из iCloud / Dropbox / GoogleDrive через встроенное приложение Files iOS11 +, и мне интересно, что я что-то упустил.

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

Это мой код:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)urlToOpen sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    if([urlToOpen isFileURL])  // <<< this goes through
    {
        if([[NSFileManager defaultManager] isReadableFileAtPath:urlToOpen.path])
        {
            // <<< this doesn't
        }
   }
}

Пример рабочих путей:

/private/var/mobile/Containers/Data/Application/F99A3EA4-457C-4043-AEB3-A9D961184360/Documents/plane.obj
/private/var/mobile/Containers/Data/Application/F99A3EA4-457C-4043-AEB3-A9D961184360/Documents/Inbox/cube.obj

Примеры путей, которые не работают:

/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/somedir/somefile.ext
/private/var/mobile/Containers/Shared/AppGroup/A7FA40A0-2C7D-4FC1-BF21-A8E88B106FF9/File Provider Storage/7791941/local-storage/L3dzX3JhZmFfemFiYWxhL2Jhc2VvcmNfbWVzaC5vYmo=/somefile.ext

Как уВы можете видеть, что оба файла, которые работали, скопировали свои данные в мой локальный каталог приложений на устройстве.

Как я могу открыть эти файлы?Обратите внимание, что я упомянул, что приложение использует большие файлы, потому что оно делает, поэтому я не могу получить их копию в памяти, это не очень поможет, мне нужно найти путь к файлу, чтобы я мог сделать отображение памятии загружаю то, что нужно в нужное время.

Я немного читал об открытых на месте и т. д., но это не относится к типу приложения, которое я разрабатываю, так как оно не работает на одном«элемент» больших файлов, о которых я упоминаю, является лишь одним из возможных источников, и поэтому такие вещи, как то, что я видел в отношении открытия на месте, не применимы к моему делу.

Есть ли способзаставить приложение иметь доступ к этим файлам напрямую или, по крайней мере, скопировать их во временную директорию с изолированными программными приложениями, чтобы я мог напрямую отобразить их в памяти?

Ура!

1 Ответ

0 голосов
/ 15 декабря 2018

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

Оказывается, что NSURL, которые вы даете в AppDelegate, защищены, ваша самая безопасная ставка - либо прочитать их, либо скопировать на локальный диск.

Я закончил с этим:

NSString* urlPath = url.path;
if(![[NSFileManager defaultManager] isReadableFileAtPath:urlPath])
{
    if([url startAccessingSecurityScopedResource])
    {
        NSString* docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString* destPath = [NSString stringWithFormat:@"%@/%@", docsPath, [url.path lastPathComponent]];
        urlPath = [FileHandler copyFileAtPath:url.path toPath:destPath increment:YES];
        [url stopAccessingSecurityScopedResource];
    }
}

Где copyFileAtPath: toPath: increment - это пользовательская функция, которая просто копирует файлы и увеличивает их, если они существуют, чтобы избежать перезаписи, но может быть чем угодно.

Ключевыми методами здесь являются [NSURL startAccessingSecurityScopedResource] и [NSURL stopAccessingSecurityScopedResource], важно отметить, что они должны вызываться парами (start / stop), поскольку сбой вызова stop может вызвать проблемы, поэтому метод копирования работает отлично, особенно когда эти файлы будут отображаться в памяти.(мой случай, как они большие)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...