从 iCloud 打开自定义文件到 Xamarin.iOS 应用程序不起作用
Opening custom file from iCloud into Xamarin.iOS app doesn't work
我们有 Xamarin.iOS
应用程序声明自定义文件扩展名 - *.msoisalesbak
作为导出类型声明
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.ewsgroup.msoisalesbak</string>
<key>UTTypeConformsTo</key>
<array>
<string>com.pkware.zip-archive</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<string>msoisalesbak</string>
</dict>
<key>UTTypeDescription</key>
<string>MSO&I Sales application backup file</string>
</dict>
</array>
这意味着,每当 iOS 系统检测到具有此扩展名的文件时,它将提供在我们的应用程序中打开此文件的可能性。
此外,在我们的 AppDelegate
中,我们有这样的代码来处理委托文件共享:
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
..................
var fileHandlerService = ServiceLocator.Container.Resolve<IAssociatedFileHandlerService>();
if(fileHandlerService.CanRestoreDatabaseFromOpenedAssociatedBackupFile(url))
{
...................
string filePath = url.Path;
var destinationPath = "PATH_TO_APP_INTERNAL_FOLDER"
using(FileStream sourceStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using(FileStream destinationStream = File.Create(destinationPath))
{
sourceStream.CopyTo(destinationStream);
}
....................
return true;
}
return false;
}
我们基本上仔细检查文件是否有效以及我们可以处理的东西,然后尝试将文件复制到内部存储并做一些额外的处理,这与这个问题无关。
现在,我们创建应用程序支持的自定义文件并将其放入 iCloud 下载文件夹。当我们点击那个文件时,我们的应用程序被成功打开并且 OpenUrl
委托被成功调用。但是,这样做我们会收到以下异常
System.IO.DirectoryNotFoundException: Could not find a part of the path "/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/Downloads/637569517947945130-0.12.1.msoisalesbak".
at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x00177]
这意味着,出于某种原因,OpenUrl
收到的路径对于我们的应用程序来说是不可访问的。
事实是,如果我们在电子邮件中有自定义文件,或者我们从聊天应用程序(例如 Microsoft Teams)等其他应用程序打开自定义文件,OpenUrl
就可以正常工作。但是,它不适用于 iCloud。
我们应该特别注意允许访问 iCloud 文件夹吗?我们错过了什么?
在从 iCloud“解锁”文件之前,您需要调用 startAccessingSecurityScopedResource
以使应用程序可以使用安全范围 URL 指向的资源。然后不要忘记调用 stopAccessingSecurityScopedResource
.
您还可以在 Info.plist 文件中创建一个新的布尔键 LSSupportsOpeningDocumentsInPlace
。如果设置为 true,url 将指向 iCloud 中的文件,但尚未下载。所以你无法访问该文件。如果将其设置为 false,它将在应用程序沙箱中复制文件。
我们有 Xamarin.iOS
应用程序声明自定义文件扩展名 - *.msoisalesbak
作为导出类型声明
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.ewsgroup.msoisalesbak</string>
<key>UTTypeConformsTo</key>
<array>
<string>com.pkware.zip-archive</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<string>msoisalesbak</string>
</dict>
<key>UTTypeDescription</key>
<string>MSO&I Sales application backup file</string>
</dict>
</array>
这意味着,每当 iOS 系统检测到具有此扩展名的文件时,它将提供在我们的应用程序中打开此文件的可能性。
此外,在我们的 AppDelegate
中,我们有这样的代码来处理委托文件共享:
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
..................
var fileHandlerService = ServiceLocator.Container.Resolve<IAssociatedFileHandlerService>();
if(fileHandlerService.CanRestoreDatabaseFromOpenedAssociatedBackupFile(url))
{
...................
string filePath = url.Path;
var destinationPath = "PATH_TO_APP_INTERNAL_FOLDER"
using(FileStream sourceStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using(FileStream destinationStream = File.Create(destinationPath))
{
sourceStream.CopyTo(destinationStream);
}
....................
return true;
}
return false;
}
我们基本上仔细检查文件是否有效以及我们可以处理的东西,然后尝试将文件复制到内部存储并做一些额外的处理,这与这个问题无关。
现在,我们创建应用程序支持的自定义文件并将其放入 iCloud 下载文件夹。当我们点击那个文件时,我们的应用程序被成功打开并且 OpenUrl
委托被成功调用。但是,这样做我们会收到以下异常
System.IO.DirectoryNotFoundException: Could not find a part of the path "/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/Downloads/637569517947945130-0.12.1.msoisalesbak".
at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x00177]
这意味着,出于某种原因,OpenUrl
收到的路径对于我们的应用程序来说是不可访问的。
事实是,如果我们在电子邮件中有自定义文件,或者我们从聊天应用程序(例如 Microsoft Teams)等其他应用程序打开自定义文件,OpenUrl
就可以正常工作。但是,它不适用于 iCloud。
我们应该特别注意允许访问 iCloud 文件夹吗?我们错过了什么?
在从 iCloud“解锁”文件之前,您需要调用 startAccessingSecurityScopedResource
以使应用程序可以使用安全范围 URL 指向的资源。然后不要忘记调用 stopAccessingSecurityScopedResource
.
您还可以在 Info.plist 文件中创建一个新的布尔键 LSSupportsOpeningDocumentsInPlace
。如果设置为 true,url 将指向 iCloud 中的文件,但尚未下载。所以你无法访问该文件。如果将其设置为 false,它将在应用程序沙箱中复制文件。