2017-10-03 4 views
1

Nous développons l'application mobile dans Xamarin. Comment peut ensuite être accompli dans iOS:Comment ouvrir le fichier téléchargé sur iOS

  • utilisateur télécharge un fichier depuis url (demande http est faite à l'API REST, sécurisé avec nom d'utilisateur d'authentification de base: secretKey)
  • fichier
  • est enregistré dans iOS
  • utilisateur ouvre un fichier (permis sont jpg, png, pdf, doc, docx, .png)
  • fichier
  • est ouvert en application par défaut (par exemple pour des images visionneuse d'images)

Comme les opérations de fichiers sont plate-forme spécifique, voici la définition de l'interface:

public interface IFileHelper 
{ 
    void DownloadFileAndSave(Models.DocumentModel document); 
} 

application Android:

public class FileHelper : IFileHelper 
{ 
    // download file and view status in download manager 
    public void DownloadFileAndSave(Models.DocumentModel document) 
    { 
    DownloadManager dm = (DownloadManager)Android.App.Application.Context.GetSystemService(Context.DownloadService); 
    string url = WebApiUtils.GetBaseUrl() + string.Format("Api/v1/Dms/{0}", document.UniqueId); 
    DownloadManager.Request request = new Android.App.DownloadManager.Request(Android.Net.Uri.Parse(url))); 

    request.AddRequestHeader("Authorization", "Basic " + WebApiUtils.GetEncodedCredentials(Auth.Users.Current)); 

    var downloadFile = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads); 
    string path = Path.Combine(downloadFile.AbsolutePath, document.FileName); 
    request.SetDestinationUri(Android.Net.Uri.FromFile(new Java.IO.File(path))); 
    request.SetMimeType(document.ContentType); 
    request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted); 

    dm.Enqueue(request); 
} 

Dans le fichier Android est simplement stocké sur le système de fichiers et avec l'Explorateur de fichiers qui est installé par défaut sur un Android (à savoir Mes fichiers -> stockage de périphériques -> Téléchargement), le fichier est ouvert dans l'application par défaut pour le type mime du fichier. Tout va bien sur Android.

application Apple iOS:

public class FileHelper : IFileHelper 
{ 
    public void DownloadFileAndSave(Models.DocumentModel document) 
    { 
    WebClient webClient = new WebClient(); 

    webClient.Headers.Add(HttpRequestHeader.Authorization, "Basic " + WebApiUtils.GetEncodedCredentials(Auth.Users.Current)); 
    webClient.DownloadDataAsync(new System.Uri(WebApiUtils.GetBaseUrl() + string.Format(Consts.ApiUrls.GetDocument, document.UniqueId))); 

    webClient.DownloadDataCompleted += (sender, e) => 
    { 
     byte[] content = e.Result; 
     string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), document.FileName); 

     // doesn't throw exception therefore saved ok 
     File.WriteAllBytes(path, content); 

     Uri uri = new Uri(String.Format("file://{0}", path)); 

     // doesn't work. 
     Device.OpenUri(uri); 
    }; 
    } 
} 

est-il un autre moyen d'ouvrir le fichier téléchargé à l'application par défaut. Si j'ouvre l'url par exemple http://example.com/files/file1.png il ouvre le fichier en safari, mais je ne peux pas mettre Authorization: Basic en-têtes dans Device.OpenUri. J'ai lu environ Load Non-Web Documents with WebView mais vous devez construire chaque fichier comme BundleResource.

+1

Dans votre code iOS, vous commentez pour dire qu'il n'y a aucune exception levée, êtes-vous en mesure de voir le fichier dans le chemin? –

+1

Aussi, pas sûr si vous avez vu cela, mais jetez un oeil ici https: //forums.xamarin.com/discussion/68919/device-openuri-avec-un-pdf-on-ios c'est un problème similaire à ce que vous avez, et je crois que le PO résout le problème ici aussi –

+0

@CodeWarrior merci pour le lien, j'ai manqué il. La solution fonctionne presque. Voir ma réponse ci-dessous. – broadband

Répondre

0

Comme l'a commenté Code Warrior, il existe une approche publiée sur le lien: https://forums.xamarin.com/discussion/36964/why-is-it-that-nothing-is-working-to-open-an-existing-local-pdf-file-in-the-ios-portion-of-my-pcl.

Mais Enregistrer l'image L'action ne fonctionne pas, tout le reste semble fonctionner.

public void DownloadFileAndSave(Models.DocumentModel document) 
{ 
    WebClient webClient = new WebClient(); 
    webClient.Headers.Add(HttpRequestHeader.Authorization, "Basic " + WebApiUtils.GetEncodedCredentials(Auth.Users.Current)); 

    string tempPath = Path.GetTempPath(); 
    string localFilename = Path.GetFileName(document.FileName); 
    string localPath = Path.Combine(tempPath, localFilename); 

    webClient.DownloadFileCompleted += (sender, e) => 
    { 
    Device.BeginInvokeOnMainThread(() => 
    { 
     QLPreviewItemFileSystem prevItem = new QLPreviewItemFileSystem(localFilename, localPath); // ql = quick look 
     QLPreviewController previewController = new QLPreviewController() 
     { 
     DataSource = new PreviewControllerDS(prevItem) 
     }; 
     UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(previewController, true, null); 
    }); 
    }; 

    // download file 
    Uri uri = new System.Uri(WebApiUtils.GetBaseUrl() + string.Format(Consts.ApiUrls.GetDocument, document.UniqueId)); 
    webClient.DownloadFileAsync(uri, localPath); 
} 

Lorsque Enregistrer l'image est déclenchée, je reçois l'erreur suivante:

2017-10-03 13:45:56.797 MyApp.iOS[477:61030] Video /private/var/mobile/Containers/Data/Application/33D7139A-53E0-4A2E-8C78-D3D13A2259B0/tmp/water-h2o-md.png cannot be saved to the saved photos album: Error Domain=AVFoundationErrorDomain Code=-11828 "Cannot Open" UserInfo={NSUnderlyingError=0x1c0445d60 {Error Domain=NSOSStatusErrorDomain Code=-12847 "(null)"}, NSLocalizedFailureReason=This media format is not supported., NSURL=file:///private/var/mobile/Containers/Data/Application/33D7139A-53E0-4A2E-8C78-D3D13A2259B0/tmp/water-h2o-md.png, NSLocalizedDescription=Cannot Open}

iOS l'image en tant que vidéo? Est-ce un bug sur iOS ou suis-je quelque chose qui manque?

MISE À JOUR

Il se avère que les autorisations suivantes dans le fichier était manquant Info.plist:

<key>NSPhotoLibraryUsageDescription</key> 
<string>Application needs to access photos</string> 

<!-- for iOS 11 --> 
<key>NSPhotoLibraryAddUsageDescription</key> 
<string>Application needs to access photos</string> 

maintenant Enregistrer l'image l'action travaille ok. Mais sérieusement Apple pourrait retourner erreur plus appropriée que Video image.jpg cannot be saved ...