I am using Xamarin.Forms and written the code to download the file for the iOS
platform. It is downloading the file successfully without any error. But after downloading it, I am not able to find the downloaded file in my apple device.
During debugging I found that it is showing
/var/mobile/Containers/Data/Application/1234567A-B8CD-9EF9-C850-9G73587DC7C/Documents/XF_Downloads/hausmann_abcd.jpg
path. So at which location file get saved? below is the image for the same.
I have written below code for this
public class IosDownloader : IDownloader
{
public event EventHandler<DownloadEventArgs> OnFileDownloaded;
public void DownloadFile(string url, string folder)
{
string pathToNewFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), folder);
Directory.CreateDirectory(pathToNewFolder);
try
{
WebClient webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
string pathToNewFile = Path.Combine(pathToNewFolder, Path.GetFileName(url));
webClient.DownloadFileAsync(new Uri(url), pathToNewFile);
}
catch (Exception ex)
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
}
}
private void Completed(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
}
else
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(true));
}
}
}
When a file is saved on an application it is a temporary url within the app's sandbox. To make this image file be publicly accessible through Apple's Photos, You'll have to use native code to do a request to add a new PHImageAsset to the photos library.
In forms you would need to access the native frameworks and therefore run native code. There are plenty of examples of doing this online if you don't know how to already. But here is an introduction if you want to run native code within a shared code framework. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/introduction
Here is a sample of taking that temp file URL and saving it to Photos Framework once you can code w/ native Xamarin.iOS frameworks:
public void AddImageUrlToPhotosLibrary(string urlToSaveToPhotos)
{
PHPhotoLibrary.SharedPhotoLibrary.PerformChanges(() => {
//This is bound to native https://developer.apple.com/documentation/photokit/phassetchangerequest/1624060-creationrequestforasset
//Parameter is an NSURL of path to image.
PHAssetChangeRequest.FromImage(new NSUrl(urlToSaveToPhotos));
}, (completed, error) => {
if (completed)
{
if (error != null)
{
Console.WriteLine($"Failed saving image asset {error.LocalizedDescription}");
} else
{
Console.WriteLine($"Successfully saved image to photos library.");
}
}
});
}
I am not able to find the downloaded file in my apple device.
If you use a simulator, you can directly find the folder in the mac by entering the path in the
your mac --> select Finder --> Then open the Go menu --> Click Go to Folder as I described in this thread:
Where can I find the MyDocuments folder on iPhone Simulator?
If you installed the app in a real device. You can browse the file in
Xcode --> Devices and Simulators --> download container as described in this thread:
Browse the files created on a device by the iOS application I'm developing, after downloading the container, you can right click it and choose Show Package Contents. Then you can see the folders.
You can also access the file by the path in the project.
Related
I am not able to get the images stored in Parse-Server as a file, once I reinstall the app. It works fine while a user is logged in but once the app is uninstalled only files are unable to access.It shows exception saying :- File doesn't exist . And I am not able to download image in parse server as well .It will redirect me to role section.
Tried changing version of parse in gradle.
I should be able to access images after reinstalling app. And I should be able to download image in parse.
code written to upload image-----------------------
ParseFile filename = new ParseFile("name.png", Byte);
filename.saveInBackground();
classObject.put("imagePic", filename);
classObject.saveInBackground();
Retrieving from Parse server--------------
file.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if(e == null) {
if(data != null) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,data.length);
imageView.setImageBitmap(bitmap);
}
}
});
i'm trying to open app store application programmatically in my app.
what i'm trying to do is that i'm calling a service to check at the current app version and if it needs update i should open app store application to let the user update the my app.
note: the app not published yet to the store, i'm still in coding phase.
i tried to use the following code in ViewDidLoad method, but it's not working (nothing happened):
var nsurl = new NSUrl("itms://itunes.apple.com");
UIApplication.SharedApplication.OpenUrl(nsurl);
A direct link via itms: will only work in an actual device, if you are testing on a simulator, use https://itunes.apple.com/us/genre/ios/id36?mt=8 instead.
I would recommend using itms:// link on the actual device as it prevents the redirects that user sees when using a https:// link to open iTunes.
bool isSimulator = Runtime.Arch == Arch.SIMULATOR;
NSUrl itunesLink;
if (isSimulator)
{
itunesLink = new NSUrl("https://itunes.apple.com/us/genre/ios/id36?mt=8");
}
else
{
itunesLink = new NSUrl("itms://itunes.apple.com");
}
UIApplication.SharedApplication.OpenUrl(itunesLink, new NSDictionary() { }, null);
Instead of opening the external Store app on the device, you might want to consider keeping the user inside of your app by using a SKStoreProductViewController:
bool isSimulator = Runtime.Arch == Arch.SIMULATOR;
if (!isSimulator)
{
var storeViewController = new SKStoreProductViewController();
storeViewController.Delegate = this;
var id = SKStoreProductParameterKey.ITunesItemIdentifier;
var productDictionaryKeys = new NSDictionary("SKStoreProductParameterITunesItemIdentifier", 123456789);
var parameters = new StoreProductParameters(productDictionaryKeys);
storeViewController.LoadProduct(parameters, (bool loaded, NSError error) =>
{
if ((error == null) && loaded)
{
this.PresentViewController(storeViewController, true, () =>
{
Console.WriteLine("SKStoreProductViewController Completed");
});
}
if (error != null)
{
throw new NSErrorException(error);
}
});
}
else
{
var itunesLink = new NSUrl("https://itunes.apple.com/us/genre/ios/id36?mt=8");
UIApplication.SharedApplication.OpenUrl(itunesLink, new NSDictionary() { }, null);
}
NSBundle.MainBundle.InfoDictionary["CFBundleVersion"]
Returns you the current app version.
To open the Apple Appstore just let the user navigate to the appstore link, Apple will automaticly detect that the user is using an iPhone and will open the Appstore for them.
Test yourself:
Open the following link in safari: Whatsapp in the Appstore
It will automatically open the appstore.
When you create app on iTunesConnect you can get url to your future app in AppStore even if you didn't release it yet. You can find it under App Information tab:
In your app you can just open it:
var nsurl = new NSUrl("https://itunes.apple.com/us/app/mygreatapp/id123456789");
UIApplication.SharedApplication.OpenUrl(nsurl);
I have get the Android to load a file dialog for google drive after authorization. Now I have to do it on Xamarin Form but unable to find a file picker for google drive. Does google drive have a file picker for Xamarin Form.
public void RequestGoogleDrivePicker() {
IntentSender intentSender =
Android.Gms.Drive.DriveClass.DriveApi.NewOpenFileActivityBuilder ()
.SetMimeType (new string[] { "application/pdf" })
.Build (GoogleApiClient);
try {
StartIntentSenderForResult ( intentSender, GOOGLE_REQUESTING_OPENER_CODE, null, 0, 0, 0);
} catch (Android.Content.IntentSender.SendIntentException e) {
}
}
Google Drive file browser dialog for Xamarin.Forms?
Short answer: No
Longer answer: Yes, but...
1) You either use the "native" platform Drive SDKs that contain pre-build file browser dialogs for Android and iOS and do this via a Forms' dependency service like you already started in the Xamarin.Android code in your question.
2) You skip the "native" mobile libraries, use the C# PCL-based Google Nugets in your Forms' project and build your own file dialog in Forms as there are no dialogs in these libraries as they are convenience wrappers for the Drive's REST API.
Nugets:
Google.Apis
Google.Apis.Auth
i.e. You can retrieve all the files in Drive, you would need to present these in a UI of your own design (Listview, ...), see link below for full sample:
IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute().Files;
if (files != null && files.Count > 0)
{
foreach (var file in files)
{
Console.WriteLine("{0} ({1})", file.Name, file.Id);
}
}
else
{
Console.WriteLine("No files found.");
}
Google Drive .NET Quickstart
I've started using the Xamarin UITest to verify the behaviour of my application. I wanted to make the tests logically separated (by that I mean, if one test fails the other one should not fail because of the first, they should be independent). My application has multiple activities and I could not find in the documentation how to open a specific Activity.
The closest I could find was:
[SetUp]
public void BeforeEachTest()
{
app = ConfigureApp.Android.LaunchableActivity("MyActivity").StartApp ();
}
But nothing happend. Can I do this? Is there a workaround?
Thanks
A very late response but thought i'd put it up for others to find. In order to launch the app using a specific activity UITest requires two pieces of information, the app name (or APK file path) and the activity name.
Calling StartApp() on the AndroidConfigurator will look as follows for an app that is already installed onto the device or emulator:
app = ConfigureApp
.Android
.InstalledApp("packagename")
.LaunchableActivity("activityname")
.StartApp();
Or as follow for an APK file:
app = ConfigureApp
.Android
.ApkFile("filename")
.LaunchableActivity("activityname")
.StartApp();
try this code:
if (platform == Platform.Android)
{
string currentFile = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
FileInfo fi = new FileInfo(currentFile);
string dir = fi.Directory.Parent.Parent.Parent.FullName;
var PathToAPK = Path.Combine(dir, "LetsGetNative.Droid", "bin", "Debug", "LetsGetNative.Droid.apk");
app = ConfigureApp.Android.ApkFile(PathToAPK).WaitTimes(new WaitTimes()).EnableLocalScreenshots().StartApp();
}
else
{
app = ConfigureApp.iOS.StartApp();
}
I have some code that saves an xml file to the file system.
public static void Save(T obj, string FileName)
{
if (Application.Current.HasElevatedPermissions)
{
string myDocuments = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string path = System.IO.Path.Combine(myDocuments, FileName);
using (var writer = new StreamWriter(path))
{
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, obj);
writer.Flush();
}
}
else
{
throw new Exception("Cannot Save File. Application Requires Elevated permissions.");
}
}
While debugging using Internet Explorer 10 the file is not saved to the listed path in the path variable "C:\Users\Travis\Documents\Save.xml"
I call load with the exact same path "C:\Users\Travis\Documents\Save.xml" and the file loads correctly but the file still does not exist at the listed location.
I searched the file system with no results for Save.xml but it has to exist since it is able to load after application exit.
If I access the same page using Chrome the file is created successfully at the location.
I am wondering where Internet Explorer saves the file?
I found that if I uncheck "Enable Protected Mode" in IE's Security tab then the file is created in the location as expected.