I am trying to add an image of a map generated by the google map static api in my Nativescript application (I'm using Nativescript with Vue).
I am able to make it work on Android but I have some issues on iOS.
I simply have an Image component like that <Image :src="map_source" />
And in my vue data, I have map_source: "https://maps.googleapis.com/maps/api/staticmap?&markers=48.2,2.1&path=color:red|weight:5|fillcolor:red|48.2,2.1|48.3,2.13|48.4,2.12&zoom=10&size=460x200&key=MY_API_KEY"
When I use this URL in my browser, I get the desired map.
When I use this URL in my app on Android, it displays the map correctly.
But when I use the same URL in my app on an iOS device, the map is not displayed at all.
Note: if I remove the path (e.g map_source: "https://maps.googleapis.com/maps/api/staticmap?&markers=48.2,2.1&zoom=10&size=460x200&key=MY_API_KEY", the image is correctly displayed on both Android and iOS. The error only appens when I add the path.
Is this an iOS issue or am I doing something wrong ?
I was able to find the issue thanks to #Manoj. On iOS devices, the URL was unsupported because of the "|" character. So I had to encode it like so:
let imageSourceModule = require("tns-core-modules/image-source");
let url = encodeURI("https://maps.googleapis.com/maps/api/staticmap?&markers=48.2,2.1&zoom=10&size=460x200&key=MY_API_KEY")
imageSourceModule.fromUrl(url).then(res => {
this.map_source = res;
});
Related
I have a Flutter app that can view mp4 files from a URL. (Using a video controller playing directly from the URL.) I want the user to be able to share them if they wish. As best I can tell the file has to actually exist on the device so I have broken down the steps for now into download file, invoke share.
I'm using this guide: https://retroportalstudio.medium.com/saving-files-to-application-folder-and-gallery-in-flutter-e9be2ebee92a
I need to work on ios and android. The problem is that on ios neither the filename I get from the dio downloader nor the ImageGallerySaver seem to "work" when passed to the system ShareSheet.
I'm using the flutter extensions dio, share_plus, cross_file, image_gallery_saver as I've seen recommended in various places.
File saveFile = File(directory.path + "/$fileName");
developer.log("starting download...");
await dio.download(url, saveFile.path,
onReceiveProgress: (value1, value2) {
developer.log("got progress " + value1.toString());
setState(() {
downloadProgress = value1 / value2;
});
});
_permaFile = saveFile.path;
if (Platform.isIOS) {
var galleryResult = await ImageGallerySaver.saveFile(saveFile.path,
isReturnPathOfIOS: true);
developer.log("gallery save result = " + galleryResult.toString());
_permaFile = galleryResult['filePath'];
}
After getting a directory we use dio to download the file, do some log chirping, and then save the name to an object member called _permaFile.
Then the share button triggers:
void _shareAction() async {
final box = context.findRenderObject() as RenderBox?;
final files = <XFile>[];
if (_permaFile == null) {
return;
}
developer.log("sharing file: " + _permaFile.toString());
files.add(XFile(_permaFile!));
await Share.shareXFiles(files,
text: "Event",
// subject: "Subject for Event",
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
}
This works on android device... after I download I hit share, and I can share the video to a third-party app like WhatsApp.
On ios the ShareSheet is invoked but when I share I only get the text "Event", not the video file that goes along with it.
Note that I have tried both results... setting the _permaFile to be what comes back from ImageGallerySaver but also just using what the dio downloader gives back.
Note also that the ImageGallerySaver seems to work: the video really does land and is there in the ios video lib. If I go into the Photos app I can share from there to WhatsApp and have the video get sent.
In each case I get errors like this:
[ShareSheet] error fetching item for URL:file:/var/mobile/Media/DCIM/100APPLE/IMG_0021.MP4 -- file:/// : (null)
[ShareSheet] error fetching file provider domain for URL:file:/var/mobile/Media/DCIM/100APPLE/IMG_0021.MP4 -- file:/// : (null)
[ShareSheet] error loading metadata for
documentURL:file:/var/mobile/Media/DCIM/100APPLE/IMG_0021.MP4 --
file:/// error:Error Domain=NSFileProviderInternalErrorDomain Code=0
"No valid file provider found from URL
file:/var/mobile/Media/DCIM/100APPLE/IMG_0021.MP4 -- file:///."
UserInfo={NSLocalizedDescription=No valid file provider found from URL
file:/var/mobile/Media/DCIM/100APPLE/IMG_0021.MP4 -- file:///.}
In order to test this further I built the share_plus demo app:
https://github.com/fluttercommunity/plus_plugins/tree/main/packages/share_plus/share_plus
I modified it to share videos to see what was different. The share plus example (sp_example) works for sharing videos that have been selected by the picker.
For this reason I think the problem is something I'm missing about ios video filenames/formats and possibly a built-in conversion step that happens.
Here are what the filenames look like that I see in my app:
dio download result:
file:///var/mobile/Containers/Data/Application/223BF2B9-DDF0-490E-932F-09D5F03B98B3/Library/Caches/test.mp4
ImageGallerySaver result:
file:///var/mobile/Media/DCIM/100APPLE/IMG_0019.MP4
This is what video filenames look like when they are picked and shared in sp_example:
/private/var/mobile/Containers/Data/Application/E5CB4D7C-6CDF-4AA2-8134-C4322ED7C886/tmp/trim.E6633D68-44E3-4853-A29E-A71AC95A0913.MOV
Note that it has been converted to MOV extension and the user gets trim step right in the picker that results in trim in the name.
For my purposes I don't want to go through the picker, the user is on the screen showing the video and they shouldnt have to repick, so where do I get the post-conversion ios filename that references what I just saved?
Buildfire suppor team, I'm trying to open up a new link using buildfire.navigation.openWindow and I noticed an issue on IOS with the URL parameters, as the = (equal sign) gets URL encoded. Please see my example below and the attached screenshot.
https://example.com/something?id=1654161096657Felix
is transformed to
https://example.com/something?id%3D1654161096657Felix
app code screenshot
Example URL works fine:
buildfire.navigation.openWindow("https://example.com/something?id=1654161096657Felix", "_system")
And when inspecting the new window on device I'm getting this:
I would check the server (the real URL) you are using and see if it is redirecting the url to something else.
I've been reading a lot of StackOverflow posts that discuss copying data from FileSystemStorage to Storage in CodenameOne, such as described in this answer from Shai, as seen below:
InputStream stream =
FileSystemStorage.getInstance().openInputStream(i);
OutputStream out =
Storage.getInstance().createOutputStream("MyImage");
Util.copy(stream, out);
Util.cleanup(stream);
Util.cleanup(out);`
I've been trying to do the reverse: save from Storage to FileSystemStorage in order to show a PDF in the BrowserComponent (while using iOS), but have not been able to do so. I need to show the PDF within the app (so I don't want to use Display.getInstance().execute()).
Basically, I'm trying to dynamically populate a Container with whatever files the user selects-- I am using the FileChooser library for CN1 from Steve Hannah. (Disclaimer: I have made slight modifications to this library as it used in the app I'm working on-- HOWEVER, when I choose images with this library and pull them from Storage to an Image via InputStream, they display perfectly in an ImageViewer so I know that all files are being saved correctly in Storage.)
Here is my code (with help from Steve Hannah's comment on GitHub):
//fileLocation and fileName are slightly different but both end with file extension
File file = new File(fileToUpload.getFileName());
FileSystemStorage fss = FileSystemStorage.getInstance();
InputStream is = Storage.getInstance().createInputStream(fileToUpload.getLocation());
OutputStream os = fss.openOutputStream(file.getAbsolutePath());
Util.copy(is, os);
ToastBar.Status status = ToastBar.getInstance().createStatus();
String message = file.exists() + " " + file.isFile() + file.getAbsolutePath();
status.setMessage(message);
status.setExpires(3000);
status.show();
NativeLogs.getNativeLogs();
if (Display.getInstance().getPlatformName().equals("ios")) {
//Log.p("in ios !!!!");
BrowserComponent browserComponent = new BrowserComponent();
browserComponent.setURL(file.getPath());
horizontalContainer.add(browserComponent);
}
The ToastBar displays true and true for file.exists() and file.isFile().
I stipulate iOS because as far as I've seen while researching previewing PDFs within an app, I've seen that Android needs to have a different implementation, like adding a NativeInterface with an Android library. I also saw in different answers on the Google Group that this functionality (using browserComponent to view PDFs) is only available for iOS and not on the simulator. In the simulator, I see a blank space. My iPhone just freezes and/or crashes after displaying the ToastBar (and I work on a Windows machine, so not much ability to see native logs....)
What can I do to access the file and show it in the BrowserComponent?
Thank you!
Simple solution -- the file had a space in it (eg. "Test page.pdf") and didn't show! When I used files that didn't have spaces this worked and after removing spaces in the file names, thankfully everything worked. I'll have to add code to handle this scenario.
Thanks for your help!
Is it possible to paste a copied image from the Safari browser to an Adobe AIR built iOS app?
I tried it with this image but couldn't find a solution yet.
Below is a screenshot of the copy button from the Safari browser on iOS 8:
Yes and no. You can't use the native dialogs or handling, but I believe you can access the data in the clipboard, even if it is an image.
You'll want to use Clipboard#getData() with a format of ClipboardFormats.BITMAP_FORMAT. That will give you access to the raw image data in a BitmapData object. You can then draw that BitmapData to a Bitmap container (or Image/BitmapImage if using Flex). You'll have to include a separate button for instantiating the paste process, but that isn't difficult to do.
Untested, but this should be a good place to start:
pasteButton.addEventListener(MouseEvent.CLICK, this.pasteEventHandler);
function(e:MouseEvent):void {
var clipboard:Clipboard = new Clipboard()
var bd:BitmapData = clipboard.getData(ClipboardFormats.BITMAP_FORMAT);
bitmap.bitmapData = bd;
}
I believe you'll need to handle errors in there as well, since the clipboard could contain text would either throw an error on the getData() line or return null.
I have a bunch of buttons that opens the default map application and puts something in the users system clipboard. It works fine on Android tablets, but the Iphone does nothing when the button is clicked. Here is the code:
case "MapYummyYummy":
System.setClipboard( "1665 Stelton Rd Piscataway Nj 08901" )
_callURL = "geo: 40.4978922, -74.4488224";
var targetURL:URLRequest = new URLRequest(_callURL);
navigateToURL(targetURL);
break;
Does anyone know the equivalent for this that will work on Iphone devices? thanks!
Have you tried this setData method? (I have no experience with this one, but looks like a viable alternative).
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/desktop/Clipboard.html#setData()
iOS launch maps via URL reference:
http://developer.apple.com/library/ios/#featuredarticles/iPhoneURLScheme_Reference/Articles/MapLinks.html
Querying for a location:
http://maps.apple.com/?q=cupertino
setting a start and end for directions:
http://maps.apple.com/?daddr=San+Francisco,+CA&saddr=cupertino
Hope it works for ya (looked up not tested).