How can one display a downloaded file in a WebView? - ios

I receive the path to a file that has been downloaded to the device. I try using <WebView source={{ uri }} /> to display the content: i.e. uri = '/Users/user/Library/Developer/CoreSimulator/Devices/1897591-5645-4C4F-A3CE-3DE4F7DD67C7/data/Containers/Data/Application/23485972-4B66-4DCF-8101-F419DF12CB87/Documents/RNFetchBlob_tmp/RNFetchBlobTmp_hhbjcw8zag7jqgra3mldkd'.
All I get is:
Error loading page
Domain: WebKitErrorDomain
Error Code: 102
Description: Frame load interrupted
Does WebView actually accepts files stored locally?

WebView for iOS can only open files by path that are stored in you project, not in your app’s file system unfortunately.
You can use webview to open base64encoded content of the file but passing it in the WebView url={base64encodedcontent}. Checkout this answer https://stackoverflow.com/a/41895475/4655003
You can also try something like this: https://github.com/wkh237/react-native-fetch-blob/wiki/iOS-API#iospreviewdocumentpathstring to use the native UIDocumentController to preview files.
RNFetchBlob.ios.previewDocument(pathToLocalFile)

I don't have the solution but it can help you:
Error Code: 102 occurs when webView:shouldStartLoadWithRequest:navigationType is returning NO (false).

Related

find and share a downloaded video on Flutter ios without going through picker?

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?

Load .html into WebView from iOS app Resources?

I have an HTML file (webview.html, for now) with relative links to images and .js files. I need to load it, and those linked resources into an iOS app's WKWebView. All the files are stored in Resources/Non-Localized/.
I'm attempting to load the files using the following code during viewDidLoad():
print("loadWebView: Bundle.main = ", Bundle.main); // This prints
if let htmlUrl = Bundle.main.url(forResource: "webview", withExtension: "html") {
print("htmlUrl = ", htmlUrl) // Doesn't print
webView.load(URLRequest.init(url: htmlUrl))
}
The app loads without error, but also without the contents in the webview.
I get the first print statement, but not the second, indicating something is wrong with my URL or resource bundle configuration.
What am I doing wrong? Do I need to do anything in XCode to add these files to the project? Where should I be looking for error messages that will hint me in the correct direction in the future?
I needed to add the file to the Project. I did this by simply dragging the Finder file icon to the project tree in Xcode.
Alternatively (and my final solution), I dragged the parent directory's icon, making a folder reference, and then added subdirectory parameter to .url(forResource...).
I'm still working on getting informative errors out of the WebView.

HTMLAudioElement Audio Not Playing on iOS (Ionic App)

I am using Xcode 8 and Ionic. I can get audio to play on Android but not iOS. The log from Xcode says this:
2016-07-13 18:19:44.802014 SpotShuffle[830:104683] [] <<<< FIGSANDBOX >>>> Path </private/var/mobile/Containers/Data/Application/EC634407-1752-4EE2-814E-B88353EA36B0/tmp/MediaCache> could not be converted by realpath() (requires all elements of path are present)
2016-07-13 18:19:44.803145 SpotShuffle[830:104683] [] __InternalSandboxRegisterURL_block_invoke signalled err=-12780 (kFigBaseObjectError_ParamErr) (Could not obtain realpath for specified URL) at /BuildRoot/Library/Caches/com.apple.xbs/Sources/EmbeddedCoreMediaFramework/EmbeddedCoreMedia-1847.11.1/Prototypes/Player/ClientServer/FigSandboxSupport.c line 590
Do you have any advice?
I'm getting a similar error trying to play a video in iOS 10 beta 2.
"Could not obtain realpath for specified URL"
ObtainAndRegisterSandboxExtensionForPath signalled err=-12780 (kFigBaseObjectError_ParamErr) (Could not obtain realpath for specified URL) at /BuildRoot/Library/Caches/com.apple.xbs/Sources/EmbeddedCoreMediaFramework/EmbeddedCoreMedia-1873/Prototypes/Player/ClientServer/FigSandboxSupport.c line 486
My guess is that somewhere in the file is a URL starting with "//:" instead of "http//:". Web browsers will pickup the right URL protocol from the pages URL. In Ionic and Cordova the page protocol is "file://", which might be breaking the realpath library.
try to covert your audio file to base64
mySound = new Audio("data:audio/mp3;base64,//uQBAAAAAA.... ..qq");
collectSound.play();
it may work. however it may open system player as well. need to find a way to keep the context of you app

Play downloaded Widevine Classic files from app document folder in iOS?

I am trying to play wvm files from the app documents folder since 3 days but without success...
I removed "file://" from my path but I still get 1013 error (as discussed here), does someone have some sample code or at least the procedure to follow to make it works properly?
WV_RegisterAsset(myFilePath) always return WViOsApiStatus(rawValue: 1013)
The file should exists because when I try this:
let fileManager = NSFileManager()
print(fileManager.fileExistsAtPath(myFilePath))
It returns true
Thanks in advance for your help!
Widevine Classic on iOS uses an "asset root" directory. When you initialize the library, you pass it in the settings dictionary using the key WVAssetRootKey.
After that, all local asset pathnames you pass to the library are relative to the AssetRoot.
One simple option is to use NSHomeDirectory() as the AssetRoot, and then trim it from the beginning of absolute pathnames.

PDF file download not working only for iPad specific browsers

A PDF file is generated on server side and pushed to client end for download. While the download works in all browsers on windows , fails on IPAD.
Please advise.
Specification : OS 6, Safari 6.1 , Chrome 23.0.1271.100
Please note: In this application pdf is not downloaded on to a new url (NO REDIRECTION).
General behavior: IPad browser (safari / chrome) does not support the download window, hence its expected to open the pdf and provides option to view in pdf compatible apps. Which is not currently happening.
When i debug the below servlet action code for download, the pdf file is successfully generated on server but browser on Ipad does not show :-(
Code sample :
/** Setting response Header **/
response.setHeader("Content-Type", "application/pdf");
response.setHeader("Content-Disposition", "attachment;filename=sample.pdf");
response.setHeader("Connection", "close");
response.setHeader("Cache-Control","cache");
response.setHeader("Pragma","cache");
response.setDateHeader ("Expires", dt.getTime() + 100000);
/** Writing to output **/
InputStream stream = info.getInputStream();
OutputStream os = response.getOutputStream();
try {
response.setContentType(contentType);
copy(stream, response.getOutputStream());
}
finally {
if (stream != null) {
stream.close();
}
}
After testing, the download action code pasted above appeared to be working fine as the issue was BROWSER specific.
Andriod Tablet - Firefox browser downloads the pdf onto pop up window.
IPad : Safari - FIX: Forced the content to open up in a new tab, something like this :
window.open(print_url);
where print_url is the baseurl+action.do+additional_parameter.
To display a pdf instead of asking the browser to save it, use "inline" instead of "attachment".
response.setHeader("Content-Disposition", "inline;filename=sample.pdf");
Also, you're setting content type twice, once in the header and once using setContentType().
I'm not sure if those two headers interact or cancel each other out, so can't say for sure that it's a source of error, but it seems like something to consider changing.

Resources