diff --git a/src/App/App.csproj b/src/App/App.csproj index 81fac9719..1b6b0475a 100644 --- a/src/App/App.csproj +++ b/src/App/App.csproj @@ -215,6 +215,11 @@ True AppResources.hi.resx + + True + True + AppResources.hr.resx + True True @@ -240,6 +245,11 @@ True AppResources.pt-PT.resx + + True + True + AppResources.ro.resx + True True @@ -329,6 +339,10 @@ ResXFileCodeGenerator AppResources.hi.Designer.cs + + ResXFileCodeGenerator + AppResources.hr.Designer.cs + ResXFileCodeGenerator AppResources.id.Designer.cs @@ -349,6 +363,10 @@ ResXFileCodeGenerator AppResources.pt-PT.Designer.cs + + ResXFileCodeGenerator + AppResources.ro.Designer.cs + ResXFileCodeGenerator AppResources.ru.Designer.cs diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs index 6549689ee..0c98919a7 100644 --- a/src/App/Resources/AppResources.Designer.cs +++ b/src/App/Resources/AppResources.Designer.cs @@ -448,6 +448,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Camera. + /// + public static string Camera { + get { + return ResourceManager.GetString("Camera", resourceCulture); + } + } + /// /// Looks up a localized string similar to Scanning will happen automatically.. /// @@ -1708,6 +1717,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Photos. + /// + public static string Photos { + get { + return ResourceManager.GetString("Photos", resourceCulture); + } + } + /// /// Looks up a localized string similar to Possible Matching Logins. /// diff --git a/src/App/Resources/AppResources.hr.Designer.cs b/src/App/Resources/AppResources.hr.Designer.cs new file mode 100644 index 000000000..e69de29bb diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx index c16f1b227..cc40859a0 100644 --- a/src/App/Resources/AppResources.resx +++ b/src/App/Resources/AppResources.resx @@ -944,4 +944,10 @@ Scan QR Code + + Camera + + + Photos + \ No newline at end of file diff --git a/src/App/Resources/AppResources.ro.Designer.cs b/src/App/Resources/AppResources.ro.Designer.cs new file mode 100644 index 000000000..e69de29bb diff --git a/src/iOS/Entitlements.plist b/src/iOS/Entitlements.plist index 0597ce385..b26e2dbd5 100644 --- a/src/iOS/Entitlements.plist +++ b/src/iOS/Entitlements.plist @@ -10,9 +10,9 @@ $(AppIdentifierPrefix)com.8bit.bitwarden - com.apple.developer.ubiquity-container-identifiers - - $(TeamIdentifierPrefix)com.8bit.bitwarden - + com.apple.developer.ubiquity-container-identifiers + + iCloud.$(CFBundleIdentifier) + diff --git a/src/iOS/Services/DeviceActionService.cs b/src/iOS/Services/DeviceActionService.cs index 24ec0e519..798c7c21c 100644 --- a/src/iOS/Services/DeviceActionService.cs +++ b/src/iOS/Services/DeviceActionService.cs @@ -4,6 +4,7 @@ using UIKit; using Foundation; using System.IO; using MobileCoreServices; +using Bit.App.Resources; namespace Bit.iOS.Services { @@ -88,65 +89,87 @@ namespace Bit.iOS.Services public byte[] SelectFile() { var controller = GetVisibleViewController(); + var picker = new UIDocumentMenuViewController(new string[] { UTType.Data }, UIDocumentPickerMode.Import); - var allowedUTIs = new string[] - { - UTType.AliasFile, - UTType.AliasRecord, - UTType.AppleICNS, - UTType.Image, - UTType.Movie, - UTType.GIF, - UTType.Video, - UTType.Folder, - UTType.ApplicationFile, - UTType.JPEG, - UTType.PNG, - UTType.BMP, - UTType.Spreadsheet - }; - - var picker = new UIDocumentMenuViewController(allowedUTIs, UIDocumentPickerMode.Open); - picker.AddOption("Camera", null, UIDocumentMenuOrder.First, () => + picker.AddOption(AppResources.Camera, null, UIDocumentMenuOrder.First, () => { var imagePicker = new UIImagePickerController { SourceType = UIImagePickerControllerSourceType.Camera }; - - imagePicker.FinishedPickingMedia += (sender, ev) => - { - //var filepath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "tmp.png"); - //var image = (UIImage)ev.Info.ObjectForKey(new NSString("UIImagePickerControllerOriginalImage")); - //DismissViewController(true, null) - }; - - imagePicker.Canceled += (sender, ev2) => - { - //DismissViewController(true, null) - }; - + imagePicker.FinishedPickingMedia += ImagePicker_FinishedPickingMedia; + imagePicker.Canceled += ImagePicker_Canceled; controller.PresentModalViewController(imagePicker, true); }); - picker.AddOption("Photo Library", null, UIDocumentMenuOrder.First, () => + + picker.AddOption(AppResources.Photos, null, UIDocumentMenuOrder.First, () => { var imagePicker = new UIImagePickerController { SourceType = UIImagePickerControllerSourceType.PhotoLibrary }; - - imagePicker.FinishedPickingMedia += (sender, ev) => - { - //var filepath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "tmp.png"); - //var image = (UIImage)ev.Info.ObjectForKey(new NSString("UIImagePickerControllerOriginalImage")); - //DismissViewController(true, null) - }; - - imagePicker.Canceled += (sender, ev2) => - { - //DismissViewController(true, null) - }; - + imagePicker.FinishedPickingMedia += ImagePicker_FinishedPickingMedia; + imagePicker.Canceled += ImagePicker_Canceled; controller.PresentModalViewController(imagePicker, true); }); - controller.PresentViewController(picker, true, null); + picker.DidPickDocumentPicker += (sender, e) => + { + controller.PresentViewController(e.DocumentPicker, true, null); + e.DocumentPicker.DidPickDocument += DocumentPicker_DidPickDocument; + }; + controller.PresentViewController(picker, true, null); return null; } + + private void ImagePicker_FinishedPickingMedia(object sender, UIImagePickerMediaPickedEventArgs e) + { + if(sender is UIImagePickerController picker) + { + //var image = (UIImage)e.Info.ObjectForKey(new NSString("UIImagePickerControllerOriginalImage")); + + // TODO: determine if JPG or PNG from extension. Get filename somehow? + byte[] data; + if(false) + { + using(var imageData = e.OriginalImage.AsJPEG()) + { + data = new byte[imageData.Length]; + System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, data, 0, + Convert.ToInt32(imageData.Length)); + } + } + else + { + using(var imageData = e.OriginalImage.AsPNG()) + { + data = new byte[imageData.Length]; + System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, data, 0, + Convert.ToInt32(imageData.Length)); + } + } + + picker.DismissViewController(true, null); + } + } + + private void ImagePicker_Canceled(object sender, EventArgs e) + { + if(sender is UIImagePickerController picker) + { + picker.DismissViewController(true, null); + } + } + + private void DocumentPicker_DidPickDocument(object sender, UIDocumentPickedEventArgs e) + { + e.Url.StartAccessingSecurityScopedResource(); + var fileCoordinator = new NSFileCoordinator(); + + // TODO: get filename? + + NSError error; + fileCoordinator.CoordinateRead(e.Url, NSFileCoordinatorReadingOptions.WithoutChanges, out error, (url) => + { + var data = NSData.FromUrl(url).ToArray(); + }); + + e.Url.StopAccessingSecurityScopedResource(); + } } }