static Task PlatformRequestAsync(ShareMultipleFilesRequest request) { var items = new List <NSObject>(); var hasTitel = !string.IsNullOrWhiteSpace(request.Title); foreach (var file in request.Files) { var fileUrl = NSUrl.FromFilename(file.FullPath); if (hasTitel) { items.Add(new ShareActivityItemSource(fileUrl, request.Title)); // Share with title (subject) } else { items.Add(fileUrl); // No title specified } } var activityController = new UIActivityViewController(items.ToArray(), null); var vc = Platform.GetCurrentViewController(); if (activityController.PopoverPresentationController != null) { activityController.PopoverPresentationController.SourceView = vc.View; if (request.PresentationSourceBounds != Rectangle.Empty || Platform.HasOSVersion(13, 0)) { activityController.PopoverPresentationController.SourceRect = request.PresentationSourceBounds.ToPlatformRectangle(); } } return(vc.PresentViewControllerAsync(activityController, true)); }
static Task PlatformRequestAsync(ShareTextRequest request) { var items = new List <NSObject>(); if (!string.IsNullOrWhiteSpace(request.Text)) { items.Add(new ShareActivityItemSource(new NSString(request.Text), request.Title)); } if (!string.IsNullOrWhiteSpace(request.Uri)) { items.Add(new ShareActivityItemSource(NSUrl.FromString(request.Uri), request.Title)); } var activityController = new UIActivityViewController(items.ToArray(), null); var vc = Platform.GetCurrentViewController(); if (activityController.PopoverPresentationController != null) { activityController.PopoverPresentationController.SourceView = vc.View; if (request.PresentationSourceBounds != Rectangle.Empty || Platform.HasOSVersion(13, 0)) { activityController.PopoverPresentationController.SourceRect = request.PresentationSourceBounds.ToPlatformRectangle(); } } return(vc.PresentViewControllerAsync(activityController, true)); }
static void PlatformLongPress() { if (Platform.HasOSVersion(10, 0)) { var impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Medium); impact.Prepare(); impact.ImpactOccurred(); impact.Dispose(); } }
static void PlatformClick() { if (Platform.HasOSVersion(10, 0)) { var impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Light); impact.Prepare(); impact.ImpactOccurred(); impact.Dispose(); } }
static Task <IEnumerable <FileResult> > PlatformPickAsync(PickOptions options, bool allowMultiple = false) { if (allowMultiple && !Platform.HasOSVersion(11, 0)) { throw new FeatureNotSupportedException("Multiple file picking is only available on iOS 11 or later."); } var allowedUtis = options?.FileTypes?.Value?.ToArray() ?? new string[] { UTType.Content, UTType.Item, "public.data" }; var tcs = new TaskCompletionSource <IEnumerable <FileResult> >(); // Note: Importing (UIDocumentPickerMode.Import) makes a local copy of the document, // while opening (UIDocumentPickerMode.Open) opens the document directly. We do the // latter, so the user accesses the original file. var documentPicker = new UIDocumentPickerViewController(allowedUtis, UIDocumentPickerMode.Open); documentPicker.AllowsMultipleSelection = allowMultiple; documentPicker.Delegate = new PickerDelegate { PickHandler = urls => { try { // there was a cancellation if (urls?.Any() ?? false) { tcs.TrySetResult(urls.Select(url => new UIDocumentFileResult(url))); } else { tcs.TrySetResult(Enumerable.Empty <FileResult>()); } } catch (Exception ex) { // pass exception to task so that it doesn't get lost in the UI main loop tcs.SetException(ex); } } }; var parentController = Platform.GetCurrentViewController(); parentController.PresentViewController(documentPicker, true, null); return(tcs.Task); }
static async Task <bool> PlatformOpenAsync(Uri uri, BrowserLaunchOptions options) { var nativeUrl = new NSUrl(uri.AbsoluteUri); switch (options.LaunchMode) { case BrowserLaunchMode.SystemPreferred: var sfViewController = new SFSafariViewController(nativeUrl, false); var vc = Platform.GetCurrentViewController(); if (options.PreferredToolbarColor.HasValue) { sfViewController.PreferredBarTintColor = options.PreferredToolbarColor.Value.ToPlatformColor(); } if (options.PreferredControlColor.HasValue) { sfViewController.PreferredControlTintColor = options.PreferredControlColor.Value.ToPlatformColor(); } if (sfViewController.PopoverPresentationController != null) { sfViewController.PopoverPresentationController.SourceView = vc.View; } if (options.HasFlag(BrowserLaunchFlags.PresentAsFormSheet)) { sfViewController.ModalPresentationStyle = UIModalPresentationStyle.FormSheet; } else if (options.HasFlag(BrowserLaunchFlags.PresentAsPageSheet)) { sfViewController.ModalPresentationStyle = UIModalPresentationStyle.PageSheet; } await vc.PresentViewControllerAsync(sfViewController, true); break; case BrowserLaunchMode.External: if (Platform.HasOSVersion(10, 0)) { return(await UIApplication.SharedApplication.OpenUrlAsync(nativeUrl, new UIApplicationOpenUrlOptions())); } else { UIApplication.SharedApplication.OpenUrl(nativeUrl); } break; } return(true); }
internal static CLAuthorizationStatus GetAuthorizationStatus(this CLLocationManager locationManager) { #if !__MACOS__ // this is coming in macOS 11 #if __WATCHOS__ if (Platform.HasOSVersion(7, 0)) #else if (Platform.HasOSVersion(14, 0)) #endif { return(locationManager.AuthorizationStatus); } #endif return(CLLocationManager.Status); }
static AppTheme PlatformRequestedTheme() { if (!Platform.HasOSVersion(13, 0)) { return(AppTheme.Unspecified); } return(Platform.GetCurrentViewController().TraitCollection.UserInterfaceStyle switch { UIUserInterfaceStyle.Light => AppTheme.Light, UIUserInterfaceStyle.Dark => AppTheme.Dark, _ => AppTheme.Unspecified });
static Task <bool> PlatformTryOpenAsync(Uri uri) { var nativeUrl = GetNativeUrl(uri); var canOpen = UIApplication.SharedApplication.CanOpenUrl(nativeUrl); if (canOpen) { if (Platform.HasOSVersion(10, 0)) { return(UIApplication.SharedApplication.OpenUrlAsync(nativeUrl, new UIApplicationOpenUrlOptions())); } UIApplication.SharedApplication.OpenUrl(nativeUrl); } return(Task.FromResult(canOpen)); }
internal static CLAuthorizationStatus GetAuthorizationStatus(this CLLocationManager locationManager) { #if __MACOS__ if (DeviceInfo.Version >= new Version(11, 0)) #elif __WATCHOS__ if (Platform.HasOSVersion(7, 0)) #else if (Platform.HasOSVersion(14, 0)) #endif { // return locationManager.AuthorizationStatus; var sel = ObjCRuntime.Selector.GetHandle("authorizationStatus"); return(CLAuthorizationStatus_objc_msgSend(locationManager.Handle, sel)); } return(CLLocationManager.Status); }
static async Task PlatformRequestAsync(ShareTextRequest request) { var src = new TaskCompletionSource <bool>(); var items = new List <NSObject>(); if (!string.IsNullOrWhiteSpace(request.Text)) { items.Add(new ShareActivityItemSource(new NSString(request.Text), request.Title)); } if (!string.IsNullOrWhiteSpace(request.Uri)) { items.Add(new ShareActivityItemSource(NSUrl.FromString(request.Uri), request.Title)); } var activityController = new UIActivityViewController(items.ToArray(), null) { CompletionWithItemsHandler = (a, b, c, d) => { src.TrySetResult(true); } }; var vc = Platform.GetCurrentViewController(); if (activityController.PopoverPresentationController != null) { activityController.PopoverPresentationController.SourceView = vc.View; if (request.PresentationSourceBounds != Rectangle.Empty || Platform.HasOSVersion(13, 0)) { activityController.PopoverPresentationController.SourceRect = request.PresentationSourceBounds.ToPlatformRectangle(); } } await vc.PresentViewControllerAsync(activityController, true); await src.Task; }
static async Task <IEnumerable <FileResult> > PlatformPickAsync(PickOptions options, bool allowMultiple = false) { var allowedUtis = options?.FileTypes?.Value?.ToArray() ?? new string[] { UTType.Content, UTType.Item, "public.data" }; var tcs = new TaskCompletionSource <IEnumerable <FileResult> >(); // Use Open instead of Import so that we can attempt to use the original file. // If the file is from an external provider, then it will be downloaded. using var documentPicker = new UIDocumentPickerViewController(allowedUtis, UIDocumentPickerMode.Open); if (Platform.HasOSVersion(11, 0)) { documentPicker.AllowsMultipleSelection = allowMultiple; } documentPicker.Delegate = new PickerDelegate { PickHandler = urls => GetFileResults(urls, tcs) }; if (documentPicker.PresentationController != null) { documentPicker.PresentationController.Delegate = new PickerPresentationControllerDelegate { PickHandler = urls => GetFileResults(urls, tcs) }; } var parentController = Platform.GetCurrentViewController(); parentController.PresentViewController(documentPicker, true, null); return(await tcs.Task); }
static FileResult DictionaryToMediaFile(NSDictionary info) { if (info == null) { return(null); } PHAsset phAsset = null; NSUrl assetUrl = null; if (Platform.HasOSVersion(11, 0)) { assetUrl = info[UIImagePickerController.ImageUrl] as NSUrl; // Try the MediaURL sometimes used for videos if (assetUrl == null) { assetUrl = info[UIImagePickerController.MediaURL] as NSUrl; } if (assetUrl != null) { if (!assetUrl.Scheme.Equals("assets-library", StringComparison.InvariantCultureIgnoreCase)) { return(new UIDocumentFileResult(assetUrl)); } phAsset = info.ValueForKey(UIImagePickerController.PHAsset) as PHAsset; } } if (phAsset == null) { assetUrl = info[UIImagePickerController.ReferenceUrl] as NSUrl; if (assetUrl != null) { phAsset = PHAsset.FetchAssets(new NSUrl[] { assetUrl }, null)?.LastObject as PHAsset; } } if (phAsset == null || assetUrl == null) { var img = info.ValueForKey(UIImagePickerController.OriginalImage) as UIImage; var imgUrl = info.ValueForKey(UIImagePickerController.ImageUrl) as NSString; if (img != null) { var rotatedImg = CorrectImageRotation(img); return(new UIImageFileResult(rotatedImg ?? img)); } } if (phAsset == null || assetUrl == null) { return(null); } string originalFilename; if (Platform.HasOSVersion(9, 0)) { originalFilename = PHAssetResource.GetAssetResources(phAsset).FirstOrDefault()?.OriginalFilename; } else { originalFilename = phAsset.ValueForKey(new NSString("filename")) as NSString; } return(new PHAssetFileResult(assetUrl, phAsset, originalFilename)); }
static async Task <FileResult> PhotoAsync(MediaPickerOptions options, bool photo, bool pickExisting) { var sourceType = pickExisting ? UIImagePickerControllerSourceType.PhotoLibrary : UIImagePickerControllerSourceType.Camera; var mediaType = photo ? UTType.Image : UTType.Movie; if (!UIImagePickerController.IsSourceTypeAvailable(sourceType)) { throw new FeatureNotSupportedException(); } if (!UIImagePickerController.AvailableMediaTypes(sourceType).Contains(mediaType)) { throw new FeatureNotSupportedException(); } if (!photo) { await Permissions.EnsureGrantedAsync <Permissions.Microphone>(); } // permission is not required on iOS 11 for the picker if (!Platform.HasOSVersion(11, 0)) { await Permissions.EnsureGrantedAsync <Permissions.Photos>(); } var vc = Platform.GetCurrentViewController(true); picker = new UIImagePickerController(); picker.SourceType = sourceType; picker.MediaTypes = new string[] { mediaType }; picker.AllowsEditing = false; if (!photo && !pickExisting) { picker.CameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Video; } if (!string.IsNullOrWhiteSpace(options?.Title)) { picker.Title = options.Title; } if (DeviceInfo.Idiom == DeviceIdiom.Tablet && picker.PopoverPresentationController != null && vc.View != null) { picker.PopoverPresentationController.SourceRect = vc.View.Bounds; } var tcs = new TaskCompletionSource <FileResult>(picker); picker.Delegate = new PhotoPickerDelegate { CompletedHandler = info => tcs.TrySetResult(DictionaryToMediaFile(info)) }; await vc.PresentViewControllerAsync(picker, true); var result = await tcs.Task; await vc.DismissViewControllerAsync(true); picker?.Dispose(); picker = null; return(result); }
internal static Task <bool> PlatformOpenAsync(NSUrl nativeUrl) => Platform.HasOSVersion(10, 0) ? UIApplication.SharedApplication.OpenUrlAsync(nativeUrl, new UIApplicationOpenUrlOptions()) : Task.FromResult(UIApplication.SharedApplication.OpenUrl(nativeUrl));
static async Task <FileResult> PhotoAsync(MediaPickerOptions options, bool photo, bool pickExisting) { var sourceType = pickExisting ? UIImagePickerControllerSourceType.PhotoLibrary : UIImagePickerControllerSourceType.Camera; var mediaType = photo ? UTType.Image : UTType.Movie; if (!UIImagePickerController.IsSourceTypeAvailable(sourceType)) { throw new FeatureNotSupportedException(); } if (!UIImagePickerController.AvailableMediaTypes(sourceType).Contains(mediaType)) { throw new FeatureNotSupportedException(); } // microphone only needed if video will be captured if (!photo && !pickExisting) { await Permissions.EnsureGrantedAsync <Permissions.Microphone>(); } // Check if picking existing or not and ensure permission accordingly as they can be set independently from each other if (pickExisting && !Platform.HasOSVersion(11, 0)) { await Permissions.EnsureGrantedAsync <Permissions.Photos>(); } if (!pickExisting) { await Permissions.EnsureGrantedAsync <Permissions.Camera>(); } var vc = Platform.GetCurrentViewController(true); picker = new UIImagePickerController(); picker.SourceType = sourceType; picker.MediaTypes = new string[] { mediaType }; picker.AllowsEditing = false; if (!photo && !pickExisting) { picker.CameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Video; } if (!string.IsNullOrWhiteSpace(options?.Title)) { picker.Title = options.Title; } if (DeviceInfo.Idiom == DeviceIdiom.Tablet && picker.PopoverPresentationController != null && vc.View != null) { picker.PopoverPresentationController.SourceRect = vc.View.Bounds; } var tcs = new TaskCompletionSource <FileResult>(picker); picker.Delegate = new PhotoPickerDelegate { CompletedHandler = async info => { GetFileResult(info, tcs); await vc.DismissViewControllerAsync(true); } }; if (picker.PresentationController != null) { picker.PresentationController.Delegate = new PhotoPickerPresentationControllerDelegate { CompletedHandler = info => GetFileResult(info, tcs) }; } await vc.PresentViewControllerAsync(picker, true); var result = await tcs.Task; picker?.Dispose(); picker = null; return(result); }