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();
+ }
}
}