-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unable to access ApplicationDocumentsDirectory in real Ios devices #748
Comments
As the official API documentation says, the So, to make it work in your scenario, you should save your Here is your code example updated (also with import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:path_provider/path_provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late String dirPath;
@override
void initState() {
setInit();
super.initState();
}
setInit() async {
String dPath = (await getApplicationDocumentsDirectory()).path;
setState(() {
dirPath = dPath;
});
}
Future<File> _downloadFile({required String url, required String filename}) async {
var httpClient = new HttpClient();
var request = await httpClient.getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
File file = new File('$dirPath/$filename');
await file.writeAsBytes(bytes);
print("downloaded $filename");
return file;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(
onPressed: () async {
await _downloadFile(
url:
"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css",
filename: "bootstrap.min.css");
await _downloadFile(
url:
"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js",
filename: "bootstrap.min.js");
await _downloadFile(
url:
"https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js",
filename: "jquery.min.js");
final snackBar = SnackBar(
content: Text('Assets downloaded! Open your WebView!'),
duration: Duration(seconds: 1),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
},
child: SizedBox(
height: 50, width: 100, child: Text("download asset first")),
),
InkWell(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => WebviewPage(dirPath)));
},
child: SizedBox(
height: 50, width: 100, child: Text("then Load Webview")),
),
],
),
),
);
}
}
class WebviewPage extends StatefulWidget {
String dirPath;
WebviewPage(this.dirPath);
@override
WebviewPageStete createState() => WebviewPageStete();
}
class WebviewPageStete extends State<WebviewPage> {
late File pageHtmlFile;
@override
void initState() {
String pageHtmlData = """
<!doctype html>
<html>
<head>
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="bootstrap.min.js"></script>
<link href="bootstrap.min.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class="jumbotron text-center">
<h1>My First Bootstrap Page</h1>
<p>Resize this responsive page to see the effect!</p>
</div>
<div class="container">
<div class="row">
<div class="col-sm-4">
<h3>Column 1</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p>
</div>
<div class="col-sm-4">
<h3>Column 2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p>
</div>
<div class="col-sm-4">
<h3>Column 3</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p>
</div>
</div>
</div>
</body>
</html>
""";
pageHtmlFile = new File('${widget.dirPath}/page.html');
pageHtmlFile.writeAsBytesSync(utf8.encode(pageHtmlData));
super.initState();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Webview"),
),
body: InAppWebView(
initialUrlRequest: URLRequest(url: Uri.parse('file://${pageHtmlFile.path}')),
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
minimumFontSize: 25,
cacheEnabled: false,
javaScriptEnabled: true,
transparentBackground: true,
verticalScrollBarEnabled: true,
allowFileAccessFromFileURLs: true,
allowUniversalAccessFromFileURLs: true,
clearCache: true,
),
android: AndroidInAppWebViewOptions(useHybridComposition: true),
ios: IOSInAppWebViewOptions(
allowingReadAccessTo: Uri.parse("file://${widget.dirPath}/"),
),
),
onWebViewCreated: (webViewController) {
webViewController.addJavaScriptHandler(
handlerName: "getPostMessage", callback: (args) {});
},
),
);
}
} This is the screen recording: 748.mov |
Thanks for the suggestion, it is helpful, But it is not our use case. I am showing at least 100 pages caching them and loading it in PageView. i can't create 100 files on my device for each page. I need dynamic content my code is working fine I that case. i only need to access files from document directory in ios. |
Because there is no other way to do it. You don't need to store these HTML files permanently. You can simply create a new File on the fly and then delete it when you don't need it anymore (for example when you dispose the page widget showing that webpage). |
Please check it once we are using it in webview_flutter. |
Then, please share the code that you are using with |
Yes please check in below url And we are using it in pubspec.yaml like that
|
Ok, thanks! I figured it out. Didn't know that you could call |
I will add in the next release the |
Released new version @override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Webview"),
),
body: InAppWebView(
initialData: InAppWebViewInitialData(
data: pageHtml,
baseUrl: Uri.parse("file://${widget.dirPath}/"),
),
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
minimumFontSize: 25,
cacheEnabled: false,
javaScriptEnabled: true,
transparentBackground: true,
verticalScrollBarEnabled: true,
allowFileAccessFromFileURLs: true,
allowUniversalAccessFromFileURLs: true,
clearCache: true,
),
android: AndroidInAppWebViewOptions(useHybridComposition: true),
ios: IOSInAppWebViewOptions(
allowingReadAccessTo: Uri.parse("file://${widget.dirPath}/"),
),
),
onWebViewCreated: (webViewController) {
webViewController.addJavaScriptHandler(
handlerName: "getPostMessage", callback: (args) {});
},
),
);
} |
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug and a minimal reproduction of the issue. |
Environment
Device information: Apple iPhone SE
Description
Expected behavior:
It should be able to access document directory files in webview.
Current behavior:
unable to access file from ios document directory in real ios devices.
Steps to reproduce
I have made a sample app to reproduce the issue, below is the github link =>
https://github.com/uc-dve/flutter_webview
working video of webview in simulator => https://www.screencast.com/t/lFI4HAhsKDK
not working on real ios device => https://www.screencast.com/t/Ef8ELwReHhS, https://www.screencast.com/t/ea9zwx54Wy
Images
Stacktrace/Logcat
The text was updated successfully, but these errors were encountered: