Skip to content

Commit a1f2d07

Browse files
committed
feat: Save media to gallery on iOS
1 parent d2824e0 commit a1f2d07

File tree

1 file changed

+29
-41
lines changed

1 file changed

+29
-41
lines changed
Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#if __IOS__
2+
using Foundation;
23
using Photos;
34
using System;
4-
using System.Collections.Generic;
55
using System.IO;
66
using System.Threading.Tasks;
77
using UIKit;
@@ -12,65 +12,49 @@ public partial class MediaGallery
1212
{
1313
private static readonly string _requiredInfoPlistKey = HasOSVersion(14) ? "NSPhotoLibraryAddUsageDescription" : "NSPhotoLibraryUsageDescription";
1414

15-
private static Task<bool> CheckAccessPlatformAsync()
15+
private static async Task<bool> CheckAccessPlatformAsync()
1616
{
17-
if (NSBundle.MainBundle.InfoDictionary.ContainsKey(new NSString(usageKey)))
17+
if (!NSBundle.MainBundle.InfoDictionary.ContainsKey(new NSString(_requiredInfoPlistKey)))
1818
{
19-
19+
throw new InvalidOperationException($"The Info.plist file is missing the required key '{_requiredInfoPlistKey}'.");
2020
}
21-
var auth = HasOSVersion(14) ?
21+
22+
var authorizationStatus = HasOSVersion(14) ?
2223
PHPhotoLibrary.GetAuthorizationStatus(PHAccessLevel.AddOnly) :
24+
#pragma warning disable CA1422 // Deprecated API
2325
PHPhotoLibrary.AuthorizationStatus;
26+
#pragma warning restore CA1422 // Deprecated API
2427

25-
return Task.FromResult(Convert(auth));
26-
}
27-
28-
/// <summary>Request <see cref="SaveMediaPermission"/> from the user.</summary>
29-
/// <returns>The status of the permission that was requested.</returns>
30-
public override async Task<PermissionStatus> RequestAsync()
31-
{
32-
var status = await CheckStatusAsync();
33-
if (status == PermissionStatus.Granted)
34-
return status;
35-
36-
var auth = HasOSVersion(14)
37-
? await PHPhotoLibrary.RequestAuthorizationAsync(PHAccessLevel.AddOnly)
38-
: await PHPhotoLibrary.RequestAuthorizationAsync();
39-
40-
return Convert(auth);
41-
}
42-
43-
PermissionStatus Convert(PHAuthorizationStatus status)
44-
=> status switch
28+
if (!IsAuthorized(authorizationStatus))
4529
{
46-
PHAuthorizationStatus.Authorized => PermissionStatus.Granted,
47-
PHAuthorizationStatus.Limited => PermissionStatus.Granted,
48-
PHAuthorizationStatus.Denied => PermissionStatus.Denied,
49-
PHAuthorizationStatus.Restricted => PermissionStatus.Restricted,
50-
_ => PermissionStatus.Unknown,
51-
};
30+
authorizationStatus = HasOSVersion(14) ?
31+
await PHPhotoLibrary.RequestAuthorizationAsync(PHAccessLevel.AddOnly) :
32+
#pragma warning disable CA1422 // Deprecated API
33+
await PHPhotoLibrary.RequestAuthorizationAsync();
34+
#pragma warning restore CA1422 // Deprecated API
35+
}
5236

37+
return IsAuthorized(authorizationStatus);
38+
}
5339

54-
public static Task<MediaGallerySaveResult> SavePlatformAsync(MediaFileType type, Stream sourceStream, string targetFileName, bool overwrite)
40+
private static async Task SavePlatformAsync(MediaFileType type, Stream sourceStream, string targetFileName)
5541
{
56-
throw new NotImplementedException();
5742
var tempFile = Path.Combine(Path.GetTempPath(), targetFileName);
5843
try
5944
{
6045
// Write stream copy to temp
6146
using var fileStream = File.Create(tempFile);
62-
await stream.CopyToAsync(fileStream);
47+
await sourceStream.CopyToAsync(fileStream);
6348

6449
// get the file uri
6550
var fileUri = new NSUrl(tempFile);
6651

6752
await PhotoLibraryPerformChanges(() =>
6853
{
69-
using var request = type == MediaFileType.Video
70-
? PHAssetChangeRequest.FromVideo(fileUri)
71-
: PHAssetChangeRequest.FromImage(fileUri);
54+
using var request = type == MediaFileType.Image ?
55+
PHAssetChangeRequest.FromImage(fileUri) :
56+
PHAssetChangeRequest.FromVideo(fileUri);
7257
}).ConfigureAwait(false);
73-
7458
}
7559
finally
7660
{
@@ -81,7 +65,7 @@ await PhotoLibraryPerformChanges(() =>
8165

8266
static async Task PhotoLibraryPerformChanges(Action action)
8367
{
84-
var tcs = new TaskCompletionSource<Exception>(TaskCreationOptions.RunContinuationsAsynchronously);
68+
var tcs = new TaskCompletionSource<Exception?>(TaskCreationOptions.RunContinuationsAsynchronously);
8569

8670
PHPhotoLibrary.SharedPhotoLibrary.PerformChanges(
8771
() =>
@@ -96,13 +80,17 @@ static async Task PhotoLibraryPerformChanges(Action action)
9680
}
9781
},
9882
(success, error) =>
99-
tcs.TrySetResult(error != null ? new NSErrorException(error) : null));
83+
tcs.TrySetResult(error is not null ? new NSErrorException(error) : null));
10084

10185
var exception = await tcs.Task;
102-
if (exception != null)
86+
if (exception is not null)
87+
{
10388
throw exception;
89+
}
10490
}
10591

10692
private static bool HasOSVersion(int major) => UIDevice.CurrentDevice.CheckSystemVersion(major, 0);
93+
94+
private static bool IsAuthorized(PHAuthorizationStatus status) => status is PHAuthorizationStatus.Authorized or PHAuthorizationStatus.Limited;
10795
}
10896
#endif

0 commit comments

Comments
 (0)