Launching safari with an image or saving to camera roll issues - ios

I've downloaded an image from a web service and either need to open the image within safari or save it to the camera roll. I've tried to open the image in Safari, but safari doesn't open.
var safari = UIApplication.SharedApplication;
var uri = new NSUrl(path); // where the image is saved to
safari.OpenUrl(uri);
This compiles, but Safari doesn't launch
The code I have for saving to the camera roll is this
PHPhotoLibrary.SharedPhotoLibrary.PerformChanges(() =>
{
using (var pool3 = new NSAutoreleasePool())
{ pool3.InvokeOnMainThread(delegate ()
{ PHAssetChangeRequest.FromImage((UIImage)UIImage.FromFile(path));
});
}
}, (t, err) =>
{
if (!t)
{
using (var pool1 = new NSAutoreleasePool())
{
pool1.InvokeOnMainThread(delegate () {
var alert = new UIAlertView("Error saving file", "An error has occured saving your photo to the camera roll", null, "OK");
alert.Show();
};
}
else
{
using (var pool2 = new NSAutoreleasePool())
{
pool2.InvokeOnMainThread(delegate (){
var alert = new UIAlertView("Image saved", "Your image has been saved to the camera roll", null, "OK");
alert.Show();
});
};
}
});
which crashes and burns (the correct permissions have been set)
I'm at a loss as to why neither of these work as they seem to be correct.

You can't open a local path with safari, that isn't allowed on iOS (apps are sandboxed) so you'll need to use either a remote URL or have your own UIWebView or WKWebView or a SFSafariViewController to display that image in a safari like experience. Here is a blog post in the Xamarin Site about the subject.
Also here is a nice recipe in the Xamarin site to save a photo into the camera roll, you can do your own solution based on it.
Hope this helps!

Related

Xamarin.forms iOS crashes when trying to take video. Cannot debug

I have this issue where I want to make a video using the montemagno library:
private async void CreateVideo()
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
DisplayAlert("No Camera", ":( No camera available.", "OK");
return;
}
videoFile = await CrossMedia.Current.TakeVideoAsync(new Plugin.Media.Abstractions.StoreVideoOptions
{
DesiredLength = TimeSpan.FromSeconds(Constants.VIDEOLENGTH),
Quality = VideoQuality.Low,
CompressionQuality = 0
});
if (videoFile == null)
return;
//await DisplayAlert("File Location", videoFile.Path, "OK");
btn_delVideo.IsVisible = true;
grid_makeVideo.IsVisible = false;
videoStream = Converters.StreamToByteArray(videoFile.GetStream());
isVideoSet = true;
bx_reset.IsVisible = false;
btn_delVideo.IsVisible = true;
await CrossMediaManager.Current.Play(videoFile.Path);
}
This code works perfectly on android.
On iOS it crashes in production.
I cannot debug this code because it returns. The simulator does NOT have a camera, and therefore can't proceed.
I tried deploying to a real iPhone, but codesigning always failes and those provisioning profiles are the worst in the world.
I know that it at least gets to the point where it displays "no camera" so the initialise function seems to work. Therefore I belelive the issue is at TakeVideoAsync().
It crashes before even showing any camera.
I could really need some help here.
Make sure to have all the permissions set. AND DONT FORGET MICROPHONE USE ;-)

Xamarin forms: jamesmontemagno/MediaPlugin: Selected picture is rotating when added to UI in IOS app

I followed this blog for taking photos from the gallery and camera. But the selected picture is showing in right rotated form when it comes to the UI in IOS. Problem only occurs when using the camera and I have no issues with the gallery. This feature is working fine in android and UWP.
Screenshot added below:
Code of Camera:
async void CameraClick()
{
try
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("Camera", "No camera available.", "OK");
return;
}
_mediaFile = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "Sample",
Name = "test.jpg",
AllowCropping = true
});
if (_mediaFile == null)
return;
profileImage.Source = ImageSource.FromStream(() =>
{
isPicture = true;
return _mediaFile.GetStream();
});
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Exception:>" + ex);
}
}
Device : IOS SE
Version of the media plugin: 3.1.1
Control I am using to display the image : Xam.plugins.Forms.Imagecircle 2.0.2(For android and UWP I am using 1.8.1)
Gallery pictures are working fine and the issue is only when taking pictures using the camera. No issues in android and UWP part.
Cause:
This is a common experience even outside of Xamarin. It is caused by iOS.
A UIImage has a property imageOrientation, which instructs the
UIImageView and other UIImage consumers to rotate the raw image data.
There's a good chance that this flag is being saved to the exif data
in the uploaded jpeg image, but the program you use to view it is not
honoring that flag.
Solution:
In the Issues part in jamesmontemagno/MediaPlugin in Github, there are several issues like the problem you meet. Seems using GetStreamWithImageRotatedForExternalStorage will fix this issue.
You can refer to:
https://github.com/jamesmontemagno/MediaPlugin/issues/333
In another way, you can rotate the image yourself.
Here are some links that might help you:
iOS Image Orientation has Strange Behavior
iOS UIImagePickerController result image orientation after upload
iOS: Image get rotated 90 degree after saved as PNG representation data
I faced this problem in the last few months on iOS.
The solution for this is add one more line in your code that is:- SaveMetaData = false,
async void CameraClick()
{
try
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("Camera", "No camera available.", "OK");
return;
}
_mediaFile = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "Sample",
Name = "test.jpg",
AllowCropping = true,
SaveMetaData = false
});
if (_mediaFile == null)
return;
profileImage.Source = ImageSource.FromStream(() =>
{
isPicture = true;
return _mediaFile.GetStream();
});
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Exception:>" + ex);
}
}

iOS 11 application crashes when trying to add attachment from camera

I have an application that crashes when the user tries to add an attachment from the camera (however it doesn't crash when they opt to load the attachment from their Photo Library).
Here's the method that gets called when an option (either Camera or Photo Library) is selected:
public void AddMedia(UIImagePickerControllerSourceType type)
{
_imagePicker = new UIImagePickerController();
// set our source to the photo library
_imagePicker.SourceType = type;
// set what media types
_imagePicker.MediaTypes = UIImagePickerController.AvailableMediaTypes(type);
_imagePicker.FinishedPickingMedia += Handle_FinishedPickingMedia;
_imagePicker.Canceled += (sender, evt) =>
{
Console.WriteLine("picker cancelled");
_imagePicker.DismissViewController(false, () =>
{
});
};
//PresentModalViewController is depreciated in iOS6 so we use PresentViewController
Parent.PresentViewController(_imagePicker, true, null);
}
And this is the line where it crashes:
_imagePicker.SourceType = type;
Why would it crash when setting it to Camera but not Photo Library? Does it have something to do with how the enum is ordered (Photo Library = 0, Camera = 1, Saved Photos Album = 2)?
Are you trying to reproduce it on simulator? Because you don't have an access to camera on it.

How to take photo continuously using XLabs

Currently I'm developing a cross-platform app using Shared Library that able to take photos. I'm using XLabs.Forms V2.0.5782 package to do this app. I successfully developed this simple app but it only allows me to take one picture at a time.
I messed around with the codes and I managed to take multiple pictures but the problem is, the camera will be closed when I clicked 'Use Photo' and reopen again to take the next photo. What I wanted is, when I clicked 'Use Photo', the camera will reopen on the spot instead of closing and reopen.
Here's the code I did to take multiple pictures but I know it is not the right way to do it. It is in button clicked event.
IDevice device = Resolver.Resolve<IDevice>();
IMediaPicker media = device.MediaPicker;
//More codes here
async void TakePicture(object sender, System.EventArgs e)
{
var options = new CameraMediaStorageOptions()
{
PercentQuality = 50,
DefaultCamera = CameraDevice.Rear,
MaxPixelDimension = 250
};
var cancel = false;
while (!cancel)
{
await media.TakePhotoAsync(options).ContinueWith(t =>
{
if (t.IsFaulted) //If there's an error when taking photos
{
DisplayAlert("Error", "An error occurred when taking photo.\nPlease try again.", "OK");
}
else if (t.IsCanceled) //When the user click 'Cancel'
{
cancel = true;
}
else //When the user click 'Use Photo' - Here's the part where the camera will close and reopen until user click 'Cancel'
{
var img = ImageSource.FromStream(() => t.Result.Source);
picList.Add(img);
}
});
}
if (picList.Count > 0)
{
scrollParent.IsVisible = true;
imageScroll.Children.Clear();
foreach (var pl in picList)
{
var image = new Image()
{
Source = pl,
HeightRequest = 150,
HorizontalOptions = LayoutOptions.Start,
Aspect = Aspect.AspectFit,
Margin = new Thickness()
{
Right = 10
}
};
imageScroll.Children.Add(image);
}
}
}
Is it possible for me to take multiple pictures with XLabs.Forms and is there a proper way? I've search everywhere but found nothing about this. Any help will be much appreciated. Thanks!
Note:
I'm using Visual Studio for Mac Version Preview 9 (7.0 build 2943)
I've only tested on iPhone running iOS 10.2. Have not tested on Android device yet
Here's a gif showing an example of my app. I think this will make you guys have a better understanding of what I want and what is happening
Please note that 3 photos are taken in this example. The camera opens up four times. After taking each photo, I clicked 'Use Photo' on the bottom right and when the camera open on the 4th time, I clicked 'Cancel' on the bottom left to stop the loop
Thank you!

Phonegap: BarcodeScanner & Childbrowser plugins

I'm facing a problem using this 2 PhoneGap plugins: "BarcodeScanner" & "ChildBrowser" (inside an iOS app, with XCode 4 & PhoneGap 2.0).
I've a button "Scan" on my app UI. When the user clic on this button, the barcode scanner is launched.
So, in the Success function of the barcode scanner callback, I need to open the recovered URL from the scan in a new Childbrowser window (inner the app).
But the new Childbrowser window is never been opened, while the console displays "Opening Url : http://fr.wikipedia.org/" (for example).
Here is my JS part of code:
$("#btnStartScan").click(function() {
var scanBarcode = window.plugins.barcodeScanner.scan(
function(result) {
if (!result.cancelled){
openUrl(result.text);
}
},
function(error) {
navigator.notification.alert("scanning failed: " + error);
});
});
function openUrl(url)
{
try {
var root = this;
var cb = window.plugins.childBrowser;
if(cb != null) {
cb.showWebPage(url);
}
else{
alert("childbrowser is null");
}
}
catch (err) {
alert(err);
}
}
And all works fine if I call my openURL() function inside a Confirm alert callback for example, like this:
if (!result.cancelled){
navigator.notification.confirm("Confirm?",
function (b) {
if (b === 1) {
openUrl(result.text);
}
},
'Test',
'Yes, No');
}
But I need to launch the ChildBrowser window directly after a scan, without any confirm alert etc.
Does anybody know how to solve this please?
I also have this same problem.
Solve it by set timeout.
var scanBarcode = window.plugins.barcodeScanner.scan(
function(result) {
if (!result.cancelled){
setTimeout(function(){ openUrl(result.text); },500);
}
},
function(error) {
navigator.notification.alert("scanning failed: " + error);
});
I'm running into the exact same problem.
My application also has another mechanism to show a webpage besides the barcode reader and when I do that action I can see that the barcode-related page HAD loaded, but it never was shown.
In ChildBrowserViewController.m, I'm looking at the last line of loadURL() which is webView.hidden = NO; and I'm thinking that the child browser is set visible after we barcode but something about the barcode reader window caused the child browser to get set to the wrong z-order, but I'm not familiar enough with the sdk to know how to test that or try to bring it to the front.
Hope this helps target a potential area.

Resources