0

.net-standard-2.0 PCL 프로젝트를 사용하여 플랫폼 간 파일 처리를 위해 official Xamarin guide을 수행하고 있습니다. 이 앱은 Android 및 Windows 용으로 제작되었습니다.Xamarin.Forms DependencyService가 파일 처리시 인터페이스 크로스 플랫폼을 공유 할 수 없습니다.

여기에서 나에게 질문이 제기됩니다. 인터페이스 코드는 다음과 같습니다.

public interface ISaveAndLoad { 
    void SaveText (string filename, string text); 
    string LoadText (string filename); 
} 

그러나, UWP에 주어진 코드는 인터페이스 ISaveAndLoad를 구현하지 않습니다 SaveAndLoad_WinApp로 컴파일되지 않습니다

[assembly: Dependency(typeof(SaveAndLoad_WinApp))] 
namespace WindowsApp 
{ 
    // https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh758325.aspx 
    public class SaveAndLoad_WinApp : ISaveAndLoad 
    { 
     public async Task SaveTextAsync(string filename, string text) 
     { 
      StorageFolder localFolder = ApplicationData.Current.LocalFolder; 
      StorageFile sampleFile = await localFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting); 
      await FileIO.WriteTextAsync(sampleFile, text); 
     } 
     public async Task<string> LoadTextAsync(string filename) 
     { 
      StorageFolder storageFolder = ApplicationData.Current.LocalFolder; 
      StorageFile sampleFile = await storageFolder.GetFileAsync(filename); 
      string text = await Windows.Storage.FileIO.ReadTextAsync(sampleFile); 
      return text; 
     } 
    } 
} 

코드로 기록됩니다.

인터페이스를 TaskTask<string>으로 변경할 수 있다는 것을 알고 있으므로 컴파일됩니다.

그러나 문제는 Android로 돌아갑니다. UWP가 Android에없는 Windows.Storage.FileIO 것을 사용하고 있습니다. 안드로이드는 System.IO을 사용하지만, 기다릴 수있는 비동기 메소드는 가지고 있지 않습니다. UWP는 async Task<string>이 필요하므로 인터페이스를 공유 할 수 없지만 Android는 Task 대신 string 만 반환합니다.

UWP 방식에서 async을 사용하지 않는 경우 FileIO은 반대로 작동하지 않습니다. 에 대한 async void은 인터페이스 상태가 void이므로 올바르게 작동합니다. 그러나 비동기 메서드로 LoadTextasync stringTask<T>, Task 또는 void을 반환해야한다고 허용하지 않습니다.

코드를 동기식으로 실행하면서 안드로이드에서도 async를 구현할 것입니다. 그러나 Xamarin 샘플이 제대로 작동한다는 것을 보여 주므로 잘못된 결과를 얻었습니다.

여기에 오해가 있거나 구현이 누락 되었습니까? 또는 실제로 Xamarin 설명서에서 잘못 되었습니까?


업데이트 # 1 나는 SaveText에 대한 async void을 넣어 스레드가 기다리고되지 않는 문제가 있음을 인식했다. 그것은 다음 기능으로 빨리 넘어갔습니다. 그래서 실제로 UWP 용 PCL의 기능을 기다려야합니다. 그러나 Android에서의 구현은 기다릴 수없는 void입니다. 그래서 실제로 오류가 발생했습니다 ... 이 시나리오를 구현하는 방법에 대한 제안이 있습니까? 여기

내가 SaveAndLoad_WinApp이 인터페이스 ISaveAndLoad를 구현하지 않는 코드는 컴파일되지 않습니다

public static void Save(){ 
    DependencyService.Get<ISaveAndLoad>().SaveText("temp.txt", input.Text); 
} 

답변

0

내 PCL에 넣어 코드입니다.

WorkingWithFiles 문서 샘플을 다운로드 할 수 있습니다. here을 찾을 수 있습니다.

public interface ISaveAndLoad 
{ 
    Task SaveTextAsync (string filename, string text); 
    Task<string> LoadTextAsync (string filename); 
    bool FileExists (string filename); 
} 

는 UWP 안드로이드에 존재하지 않는이 Windows.Storage.FileIO 일을 사용하고 있습니다 :이 샘플에서 ISaveAndLoad 인터페이스는 약간의 차이가 있습니다. 안드로이드는 System.IO를 사용하지만, 기다릴 수있는 비동기 메소드는 가지고 있지 않습니다.

var fileService = DependencyService.Get<ISaveAndLoad>(); 
... 
saveButton.Clicked += async (sender, e) => 
{ 
    loadButton.IsEnabled = saveButton.IsEnabled = false; 
    // uses the Interface defined in this project, and the implementations that must 
    // be written in the iOS, Android and WinPhone app projects to do the actual file manipulation 

    await fileService.SaveTextAsync (fileName, input.Text); 
    loadButton.IsEnabled = saveButton.IsEnabled = true; 
}; 
이 같은 SaveTextAsync 방법을 사용하여 PCL에 그런

public class SaveAndLoad_Android : ISaveAndLoad 
{ 
    #region ISaveAndLoad implementation 

    public async Task SaveTextAsync (string filename, string text) 
    { 
     var path = CreatePathToFile (filename); 
     using (StreamWriter sw = File.CreateText (path)) 
      await sw.WriteAsync(text); 
    } 

    public async Task<string> LoadTextAsync (string filename) 
    { 
     var path = CreatePathToFile (filename); 
     using (StreamReader sr = File.OpenText(path)) 
      return await sr.ReadToEndAsync(); 
    } 

    public bool FileExists(string filename) 
    { 
     return File.Exists(CreatePathToFile(filename)); 
    } 

    #endregion 

    string CreatePathToFile(string filename) 
    { 
     var docsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); 
     return Path.Combine(docsPath, filename); 
    } 
} 

:

당신은 사용, 샘플 프로젝트에 SaveAndLoad_Android.cs 클래스에 StreamWriter.WriteAsync() 방법을 참조 할 수