{"id":1858,"date":"2020-04-22T10:15:09","date_gmt":"2020-04-22T08:15:09","guid":{"rendered":"http:\/\/web.evertop.pl\/how-to-write-a-simple-downloading-app-with-flutter\/"},"modified":"2021-04-25T22:14:28","modified_gmt":"2021-04-25T20:14:28","slug":"how-to-write-a-simple-downloading-app-with-flutter","status":"publish","type":"post","link":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/","title":{"rendered":"How To Write a Simple Downloading App With Flutter"},"content":{"rendered":"<section class=\"dy dz ea eb ec\">\n<div class=\"n p\">\n<div class=\"z ab ac ae af ed ah ai\">\n<h3 id=\"aa52\" class=\"hi hj aw ay as hk eh hl ej hm hn ho hp hq hr hs ht\">Intro<\/h3>\n<p id=\"4f10\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">In this article you will learn how to write a simple app which:<\/p>\n<ul class=\"\">\n<li id=\"98d3\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih in io ip\" data-selectable-paragraph=\"\">downloads a file,<\/li>\n<li id=\"8510\" class=\"hu hv aw ay hw b hx iq hz ir ib is id it if iu ih in io ip\" data-selectable-paragraph=\"\">shows download progress,<\/li>\n<li id=\"c5f0\" class=\"hu hv aw ay hw b hx iq hz ir ib is id it if iu ih in io ip\" data-selectable-paragraph=\"\">stores downloaded file available outside the app,<\/li>\n<li id=\"b214\" class=\"hu hv aw ay hw b hx iq hz ir ib is id it if iu ih in io ip\" data-selectable-paragraph=\"\">shows local notification with a download result,<\/li>\n<li id=\"7cb4\" class=\"hu hv aw ay hw b hx iq hz ir ib is id it if iu ih in io ip\" data-selectable-paragraph=\"\">opens downloaded file in a native app by tapping the notification.<\/li>\n<\/ul>\n<p id=\"46fe\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">If you are new to Flutter and you have never built nor created an application using Flutter, please get familiar with <a class=\"bt dg he hf hg hh\" href=\"https:\/\/flutter.dev\/docs\/get-started\/install\" target=\"_blank\" rel=\"noopener nofollow noreferrer\"><em class=\"iv\">Get started<\/em><\/a> section on the official flutter.dev website before continuing.<\/p>\n<p id=\"aacb\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">Click <a class=\"bt dg he hf hg hh\" href=\"https:\/\/flutter.dev\/docs\/get-started\/install\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">here<\/a> to find out how to set up your development environment.<\/p>\n<div class=\"media\"><span class=\"media-left\"><br \/>\n<img loading=\"lazy\" src=\"https:\/\/www.evertop.pl\/wp-content\/uploads\/2021\/02\/read-also.png\" alt=\"...\" width=\"40\" height=\"40\" \/><br \/>\n<\/span><\/p>\n<div class=\"media-body\">\n<h4 class=\"media-heading\">Read also: <a href=\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-flutter-qr-code-scanner-app\/\">How To Write a Simple Flutter QR Code Scanner App<\/a><\/h4>\n<\/div>\n<\/div>\n<h3 id=\"666d\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">End result<\/strong><\/h3>\n<p><img loading=\"lazy\" class=\"aligncenter wp-image-1700 size-large\" src=\"http:\/\/web.evertop.pl\/wp-content\/uploads\/2020\/09\/1-4ulJE76AEH7hIEoHdGA0Dg-576x1024.gif\" alt=\"\" width=\"576\" height=\"1024\" srcset=\"https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-4ulJE76AEH7hIEoHdGA0Dg-576x1024.gif 576w, https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-4ulJE76AEH7hIEoHdGA0Dg-169x300.gif 169w\" sizes=\"(max-width: 576px) 100vw, 576px\" \/><\/p>\n<section class=\"dy dz ea eb ec\">\n<div class=\"n p\">\n<div class=\"z ab ac ae af ed ah ai\">\n<h3 id=\"dc8e\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 0. Setting up the project<\/strong><\/h3>\n<p id=\"a7c1\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">First of all, create a new Flutter project if you haven\u2019t done it already \ud83d\ude42<\/p>\n<\/div>\n<section class=\"dy dz ea eb ec\">\n<div class=\"n p\">\n<div class=\"z ab ac ae af ed ah ai\">\n<h3 id=\"5a22\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 1. Adding dependencies<\/strong><\/h3>\n<p id=\"01bf\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">Let\u2019s start with a few packages that are going to help us achieving our final result. Add following dependencies to the <em class=\"iv\">pubspec.yaml<\/em> file:<\/p>\n<pre class=\"gf gg gh gi gj jl jm jn\"><span id=\"4cbd\" class=\"jo hj aw ay jp b au jq jr r js\" data-selectable-paragraph=\"\">dio: ^3.0.9\r\npath_provider: ^1.6.5\r\ndownloads_path_provider_28: ^0.1.0\r\npermission_handler: ^4.4.0+hotfix.2\r\nopen_file: ^3.0.1\r\nflutter_local_notifications: ^1.3.0<\/span><\/pre>\n<p id=\"a9ca\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\"><a class=\"bt dg he hf hg hh\" href=\"https:\/\/pub.dev\/packages\/dio\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">dio<\/a> \u2014 a powerful http client for Dart, which supports file downloading among other things,<\/p>\n<p id=\"ce4d\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\"><a class=\"bt dg he hf hg hh\" href=\"https:\/\/pub.dev\/packages\/path_provider\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">path_provider <\/a>\u2014 plugin for finding commonly used locations in the filesystem, in our case used for a particular application document directory on iOS,<\/p>\n<p id=\"4c64\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\"><a class=\"bt dg he hf hg hh\" href=\"https:\/\/pub.dev\/packages\/downloads_path_provider_28\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">downloads_path_provider_28 <\/a>\u2014 plugin to get the downloads directory on Android,<\/p>\n<p id=\"e14e\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\"><a class=\"bt dg he hf hg hh\" href=\"https:\/\/pub.dev\/packages\/permission_handler\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">permission_handler <\/a>\u2014 plugin to check and request permissions,<\/p>\n<p id=\"8c77\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\"><a class=\"bt dg he hf hg hh\" href=\"https:\/\/pub.dev\/packages\/open_file\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">open_file <\/a>\u2014plugin which can call a native app to open file with certain extension,<\/p>\n<p id=\"afcf\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\"><a class=\"bt dg he hf hg hh\" href=\"https:\/\/pub.dev\/packages\/flutter_local_notifications\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">flutter_local_notifications <\/a>\u2014 plugin for displaying local notifications.<\/p>\n<\/div>\n<\/div>\n<\/section>\n<section class=\"dy dz ea eb ec\">\n<div class=\"n p\">\n<div class=\"z ab ac ae af ed ah ai\">\n<h3 id=\"4c36\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 2. Info.plist and AndroidManifest.xml<\/strong><\/h3>\n<ul class=\"\">\n<li id=\"afb3\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih in io ip\" data-selectable-paragraph=\"\">iOS<\/li>\n<\/ul>\n<p id=\"a0d5\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">To allow arbitrary loads and to be able to see downloaded files in app directory (Locations\/On My iPhone\/&lt;app_name&gt;) you have to extend your <em class=\"iv\">info.plist <\/em>with keys listed below.<\/p>\n<pre class=\"gf gg gh gi gj jl jm jn\"><span id=\"ec2c\" class=\"jo hj aw ay jp b au jq jr r js\" data-selectable-paragraph=\"\">&lt;key&gt;NSAllowsArbitraryLoads&lt;\/key&gt;\r\n&lt;true\/&gt;\r\n&lt;key&gt;LSSupportsOpeningDocumentsInPlace&lt;\/key&gt;\r\n&lt;true\/&gt;\r\n&lt;key&gt;UIFileSharingEnabled&lt;\/key&gt;\r\n&lt;true\/&gt;<\/span><\/pre>\n<p id=\"9eef\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">Detailed info about used keys:<\/p>\n<ul class=\"\">\n<li id=\"78b3\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih in io ip\" data-selectable-paragraph=\"\">NSAllowsArbitraryLoads \u2014 <a class=\"bt dg he hf hg hh\" href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/information_property_list\/nsapptransportsecurity\/nsallowsarbitraryloads\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">click<\/a><\/li>\n<li id=\"04db\" class=\"hu hv aw ay hw b hx iq hz ir ib is id it if iu ih in io ip\" data-selectable-paragraph=\"\">LSSupportsOpeningDocumentsInPlace \u2014 <a class=\"bt dg he hf hg hh\" href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/information_property_list\/lssupportsopeningdocumentsinplace\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">click<\/a><\/li>\n<li id=\"aa6b\" class=\"hu hv aw ay hw b hx iq hz ir ib is id it if iu ih in io ip\" data-selectable-paragraph=\"\">UIFileSharingEnabled \u2014 <a class=\"bt dg he hf hg hh\" href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/information_property_list\/uifilesharingenabled\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">click<\/a><\/li>\n<\/ul>\n<p id=\"60d1\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">Setup <em class=\"iv\">flutter_local_notifications <\/em>plugin as described on the iOS integration section of the plugin <a class=\"bt dg he hf hg hh\" href=\"https:\/\/github.com\/MaikuB\/flutter_local_notifications\/tree\/master\/flutter_local_notifications#ios-integration\" target=\"_blank\" rel=\"noopener nofollow noreferrer\"><em class=\"iv\">readme<\/em><\/a>. For our needs, we just need to copy one if statement, depending on what iOS language in our project we use.<\/p>\n<p id=\"1173\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\"><em class=\"iv\">Add the following lines to the didFinishLaunchingWithOptions method in the AppDelegate.m\/AppDelegate.swift file of your iOS project<\/em><\/p>\n<p id=\"1158\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">Swift:<\/p>\n<figure class=\"gf gg gh gi gj gk\">\n<div class=\"gs r bq\">\n<pre class=\"nm r\">if #available(iOS 10.0, *) {\r\n  UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate\r\n}<\/pre>\n<\/div>\n<\/figure>\n<p id=\"32fc\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">Objective-C:<\/p>\n<figure class=\"gf gg gh gi gj gk\">\n<div class=\"gs r bq\">\n<pre class=\"nl r\">if (@available(iOS 10.0, *)) {\r\n  [UNUserNotificationCenter currentNotificationCenter].delegate = (id&lt;UNUserNotificationCenterDelegate&gt;) self;\r\n}<\/pre>\n<\/div>\n<\/figure>\n<ul class=\"\">\n<li id=\"a31f\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih in io ip\" data-selectable-paragraph=\"\">Android<\/li>\n<\/ul>\n<p id=\"6f7a\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">All we have to do in our Android project, is to add Internet and read\/write external storage permissions to <em class=\"iv\">AndroidManifest.xml<\/em> file.<\/p>\n<pre class=\"gf gg gh gi gj jl jm jn\"><span id=\"6ef5\" class=\"jo hj aw ay jp b au jq jr r js\" data-selectable-paragraph=\"\">&lt;uses-permission android:name=\"android.permission.INTERNET\" \/&gt;\r\n&lt;uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" \/&gt;\r\n&lt;uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"\/&gt;<\/span><\/pre>\n<p id=\"c03d\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">Detailed info about used permissions:<\/p>\n<ul class=\"\">\n<li id=\"3cf5\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih in io ip\" data-selectable-paragraph=\"\">android.permission.INTERNET \u2014 <a class=\"bt dg he hf hg hh\" href=\"https:\/\/developer.android.com\/reference\/android\/Manifest.permission#INTERNET\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">click<\/a><\/li>\n<li id=\"d576\" class=\"hu hv aw ay hw b hx iq hz ir ib is id it if iu ih in io ip\" data-selectable-paragraph=\"\">android.permission.READ_EXTERNAL_STORAGE \u2014 <a class=\"bt dg he hf hg hh\" href=\"https:\/\/developer.android.com\/reference\/android\/Manifest.permission#READ_EXTERNAL_STORAGE\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">click<\/a><\/li>\n<li id=\"b86a\" class=\"hu hv aw ay hw b hx iq hz ir ib is id it if iu ih in io ip\" data-selectable-paragraph=\"\">android.permission.WRITE_EXTERNAL_STORAGE \u2014 <a class=\"bt dg he hf hg hh\" href=\"https:\/\/developer.android.com\/reference\/android\/Manifest.permission#WRITE_EXTERNAL_STORAGE\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">click<\/a><\/li>\n<\/ul>\n<\/div>\n<h3 id=\"ea32\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 3. Starting point<\/strong><\/h3>\n<p id=\"c3b7\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">Copy and replace _MyHomePageState class as our starting point and let\u2019s start coding! As you can see, all I have changed in the code below are just the small things like icons and labels.<\/p>\n<pre>import 'package:flutter\/material.dart';\r\n\r\nvoid main() =&gt; runApp(MyApp());\r\n\r\nclass MyApp extends StatelessWidget {\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return MaterialApp(\r\n      title: 'Flutter Demo',\r\n      theme: ThemeData(\r\n        primarySwatch: Colors.blue,\r\n      ),\r\n      home: MyHomePage(title: 'Flutter Demo Home Page'),\r\n    );\r\n  }\r\n}\r\n\r\nclass MyHomePage extends StatefulWidget {\r\n  MyHomePage({Key key, this.title}) : super(key: key);\r\n\r\n  final String title;\r\n\r\n  @override\r\n  _MyHomePageState createState() =&gt; _MyHomePageState();\r\n}\r\n\r\nclass _MyHomePageState extends State&lt;MyHomePage&gt; {\r\n  String _progress = \"-\";\r\n\r\n  Future&lt;void&gt; _download() async {\r\n    \/\/ download\r\n  }\r\n\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return Scaffold(\r\n      appBar: AppBar(\r\n        title: Text(widget.title),\r\n      ),\r\n      body: Center(\r\n        child: Column(\r\n          mainAxisAlignment: MainAxisAlignment.center,\r\n          children: &lt;Widget&gt;[\r\n            Text(\r\n              'Download progress:',\r\n            ),\r\n            Text(\r\n              '$_progress',\r\n              style: Theme.of(context).textTheme.display1,\r\n            ),\r\n          ],\r\n        ),\r\n      ),\r\n      floatingActionButton: FloatingActionButton(\r\n        onPressed: _download,\r\n        tooltip: 'Download',\r\n        child: Icon(Icons.file_download),\r\n      ),\r\n    );\r\n  }\r\n}\r\n<\/pre>\n<h3 id=\"5c55\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 4. Resources<\/strong><\/h3>\n<p id=\"9a2d\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">To download anything, we need to have url to the file we are going to get, so let\u2019s specify it. Add two final Strings with url and filename. Just to make it simple we are going to hardcode the resources. In a real life scenario you would probably get the resource URL from your database or Web API.<\/p>\n<pre>final String _fileUrl = \"http:\/\/lot.services\/blog\/files\/DSCF0277.jpg\";\r\nfinal String _fileName = \"DSCF0277.jpg\";\r\n<\/pre>\n<h3 id=\"a308\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 5. Downloads directory path<\/strong><\/h3>\n<p id=\"01e1\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">We already know the filename and url to the file we want to download, so now it\u2019s time to get the directory where we will store it. Depending on the platform we are going to get different paths since both operating systems have different policies of storing files.<\/p>\n<p id=\"c36d\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">If you are interested in this topic, read more about it <a class=\"bt dg he hf hg hh\" href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/FileManagement\/Conceptual\/FileSystemProgrammingGuide\/FileSystemOverview\/FileSystemOverview.html\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">here <\/a>for iOS and <a class=\"bt dg he hf hg hh\" href=\"https:\/\/developer.android.com\/guide\/topics\/data\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">here <\/a>for Android.<\/p>\n<p id=\"7e78\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">The simplest way to get our download path is to use <em class=\"iv\">path_provider <\/em>and <em class=\"iv\">downloads_path_provider_28 <\/em>just like this:<\/p>\n<pre>  Future&lt;Directory&gt; _getDownloadDirectory() async {\r\n    if (Platform.isAndroid) {\r\n      return await DownloadsPathProvider.downloadsDirectory;\r\n    }\r\n\r\n    \/\/ in this example we are using only Android and iOS so I can assume\r\n    \/\/ that you are not trying it for other platforms and the if statement\r\n    \/\/ for iOS is unnecessary\r\n  \r\n    \/\/ iOS directory visible to user\r\n    return await getApplicationDocumentsDirectory();\r\n  }\r\n<\/pre>\n<h3 id=\"28f9\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 6. Storage permissions<\/strong><\/h3>\n<p id=\"c0a6\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">Check and request for the storage permissions. Even though we have added appropriate keys to our native configuration files we still need to make sure if we are allowed to access the storage.<\/p>\n<pre>  Future&lt;bool&gt; _requestPermissions() async {\r\n    var permission = await PermissionHandler().checkPermissionStatus(PermissionGroup.storage);\r\n\r\n    if (permission != PermissionStatus.granted) {\r\n      await PermissionHandler().requestPermissions([PermissionGroup.storage]);\r\n      permission = await PermissionHandler().checkPermissionStatus(PermissionGroup.storage);\r\n    }\r\n\r\n    return permission == PermissionStatus.granted;\r\n  }\r\n<\/pre>\n<h3 id=\"5a36\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 7. Download method<\/strong><\/h3>\n<p id=\"72e9\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">We already know what we want to download, where to store it and if we have sufficient permissions to do this. Actually, the next step is to download\u2026 But right before this, let\u2019s fill body of our _download() method with the things we know.<\/p>\n<pre>  Future&lt;void&gt; _download() async {\r\n    final dir = await _getDownloadDirectory();\r\n    final isPermissionStatusGranted = await _requestPermissions();\r\n\r\n    if (isPermissionStatusGranted) {\r\n      final savePath = path.join(dir.path, _fileName);\r\n      await _startDownload(savePath);\r\n    } else {\r\n      \/\/ handle the scenario when user declines the permissions\r\n    }\r\n  }\r\n<\/pre>\n<p>To combine our directory path and filename we need to import dart path package.<\/p>\n<\/div>\n<pre>import 'package:path\/path.dart' as path;\r\n\r\n<\/pre>\n<h3 id=\"47c3\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 8. Download process<\/strong><\/h3>\n<p id=\"24ac\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">Finally, it\u2019s time to download our file. Create an instance of Dio and add _startDownload() method which will download a file from the provided url to \u201csave path\u201d.<\/p>\n<pre>  final Dio _dio = Dio();\r\n\r\n  Future&lt;void&gt; _startDownload(String savePath) async {\r\n    final response = await _dio.download(\r\n      _fileUrl,\r\n      savePath\r\n    );\r\n  }\r\n<\/pre>\n<p id=\"88c9\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">To update download progress, we need to add one more method in which we will calculate the percentage download status.<\/p>\n<p id=\"6fca\" class=\"hu hv aw ay hw b hx ii hz ij ib ik id il if im ih dy\" data-selectable-paragraph=\"\">Simple as that.<\/p>\n<pre>  void _onReceiveProgress(int received, int total) {\r\n    if (total != -1) {\r\n      setState(() {\r\n        _progress = (received \/ total * 100).toStringAsFixed(0) + \"%\";\r\n      });\r\n    }\r\n  }<\/pre>\n<p>Now, to enable the process of calculating the progress, we have to pass our method as a parameter to Dio\u2019s download function.<\/p>\n<pre>  final response = await _dio.download(\r\n    _fileUrl,\r\n    savePath,\r\n    onReceiveProgress: _onReceiveProgress\r\n  );\r\n<\/pre>\n<p>Build and run the example and you should already be able to download the file and see the progress updated as shown below.<\/p>\n<p><img loading=\"lazy\" class=\"aligncenter wp-image-1702 size-large\" src=\"http:\/\/web.evertop.pl\/wp-content\/uploads\/2020\/09\/1-i671WU-ZNgP7Y1VsTXstHQ-576x1024.png\" alt=\"\" width=\"576\" height=\"1024\" srcset=\"https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-i671WU-ZNgP7Y1VsTXstHQ-576x1024.png 576w, https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-i671WU-ZNgP7Y1VsTXstHQ-169x300.png 169w, https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-i671WU-ZNgP7Y1VsTXstHQ.png 720w\" sizes=\"(max-width: 576px) 100vw, 576px\" \/><\/p>\n<h3 id=\"6b73\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 9. Local notifications initialization<\/strong><\/h3>\n<p id=\"93e2\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">Create a new instance of the <em class=\"iv\">flutter_local_notifications <\/em>plugin and initialize it.<\/p>\n<pre>FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;<\/pre>\n<p>Initialisation should only be done once and the place where this can be done is in the main function, or alternatively within the first shown page of your app. Override initState and initialize it.<\/p>\n<pre>  @override\r\n  void initState() {\r\n    super.initState();\r\n\r\n    flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();\r\n    final android = AndroidInitializationSettings('@mipmap\/ic_launcher');\r\n    final iOS = IOSInitializationSettings();\r\n    final initSettings = InitializationSettings(android, iOS);\r\n\r\n    flutterLocalNotificationsPlugin.initialize(initSettings, onSelectNotification: _onSelectNotification);\r\n  }<\/pre>\n<p>For now, add also an empty onSelectNotification method.<\/p>\n<pre>  Future&lt;void&gt; _onSelectNotification(String json) async {\r\n    \/\/ todo: handling clicked notification\r\n  }<\/pre>\n<h3 id=\"589a\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 10. Calling _showNotification method on downloads finish<\/strong><\/h3>\n<p>After the download is completed, we need to show the notification whether it has succeeded or not. Modify our _startDownload method.<\/p>\n<pre>  Future&lt;void&gt; _startDownload(String savePath) async {\r\n    Map&lt;String, dynamic&gt; result = {\r\n      'isSuccess': false,\r\n      'filePath': null,\r\n      'error': null,\r\n    };\r\n\r\n    try {\r\n      final response = await _dio.download(\r\n        _fileUrl,\r\n        savePath,\r\n        onReceiveProgress: _onReceiveProgress\r\n      );\r\n      result['isSuccess'] = response.statusCode == 200;\r\n      result['filePath'] = savePath;\r\n    } catch (ex) {\r\n      result['error'] = ex.toString();\r\n    } finally {\r\n      await _showNotification(result);\r\n    }\r\n  }<\/pre>\n<p>We have added simple Map with three values to determine if a download is completed successfully and to store a file path or error message. The logic is also closed within <em class=\"iv\">try catch finally<\/em> clause which finally calls _showNotification.<\/p>\n<h3 id=\"1748\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 11. Showing local notification<\/strong><\/h3>\n<p id=\"7458\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">Add _showNotification method. In this method we will call <em class=\"iv\">show<\/em> function to show simple notification.<\/p>\n<pre>  Future&lt;void&gt; _showNotification(Map&lt;String, dynamic&gt; downloadStatus) async {\r\n    final android = AndroidNotificationDetails(\r\n      'channel id',\r\n      'channel name',\r\n      'channel description',\r\n      priority: Priority.High,\r\n      importance: Importance.Max\r\n    );\r\n    final iOS = IOSNotificationDetails();\r\n    final platform = NotificationDetails(android, iOS);\r\n    final json = jsonEncode(downloadStatus);\r\n    final isSuccess = downloadStatus['isSuccess'];\r\n\r\n    await flutterLocalNotificationsPlugin.show(\r\n      0, \/\/ notification id\r\n      isSuccess ? 'Success' : 'Failure',\r\n      isSuccess ? 'File has been downloaded successfully!' : 'There was an error while downloading the file.',\r\n      platform,\r\n      payload: json\r\n    );\r\n  }\r\n<\/pre>\n<p>Except the basic configuration needed to show the notification I have also encoded our Map to JSON and passed it to a payload parameter. The payload String will be used in the method fired when we tap the notification.<\/p>\n<h3 id=\"d49a\" class=\"hi hj aw ay as hk eh je ej jf hn jg hp jh hr ji ht\"><strong class=\"bz\">Step 12. Handling notification tap<\/strong><\/h3>\n<p id=\"ba4a\" class=\"hu hv aw ay hw b hx hy hz ia ib ic id ie if ig ih dy\" data-selectable-paragraph=\"\">The last thing we have to do is to fulfill our empty _onSelectNotification method. Here we will just decode our encoded Map to JSON String and open downloaded file if the download succeeded or show dialog with an error message.<\/p>\n<pre>  Future&lt;void&gt; _onSelectNotification(String json) async {\r\n    final obj = jsonDecode(json);\r\n\r\n    if (obj['isSuccess']) {\r\n      OpenFile.open(obj['filePath']);\r\n    } else {\r\n      showDialog(\r\n        context: context,\r\n        builder: (_) =&gt; AlertDialog(\r\n          title: Text('Error'),\r\n          content: Text('${obj['error']}'),\r\n        ),\r\n      );\r\n    }\r\n  }<\/pre>\n<h3 id=\"0767\" class=\"hi hj aw ay as hk eh hl ej hm hn ho hp hq hr hs ht\"><strong class=\"bz\">That\u2019s it!<\/strong><\/h3>\n<p><img loading=\"lazy\" class=\"aligncenter size-full wp-image-1699\" src=\"http:\/\/web.evertop.pl\/wp-content\/uploads\/2020\/09\/1-1H1SJlIusany0hMN5lav8Q.gif\" alt=\"\" width=\"480\" height=\"270\" \/><\/p>\n<p>You can find the full example in my <a href=\"https:\/\/github.com\/lotekbard\/flutter-file-download-example\">GitHub repository<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<\/section>\n<\/div>\n<\/section>\n<\/div>\n<\/div>\n<\/section>\n","protected":false},"excerpt":{"rendered":"<p>Intro In this article you will learn how to write a simple app which: downloads a file, shows download progress, stores downloaded file available outside the app, shows local notification with a download result, opens downloaded file in a native app by tapping the notification. If you are new to Flutter and you have never [&hellip;]<\/p>\n","protected":false},"author":22,"featured_media":1701,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[13],"tags":[97,98,38],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v16.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How To Write a Simple Downloading App With Flutter - Evertop<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How To Write a Simple Downloading App With Flutter - Evertop\" \/>\n<meta property=\"og:description\" content=\"Intro In this article you will learn how to write a simple app which: downloads a file, shows download progress, stores downloaded file available outside the app, shows local notification with a download result, opens downloaded file in a native app by tapping the notification. If you are new to Flutter and you have never [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/\" \/>\n<meta property=\"og:site_name\" content=\"Evertop\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/EvertopPoland\/\" \/>\n<meta property=\"article:published_time\" content=\"2020-04-22T08:15:09+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-04-25T20:14:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-GD1sSLAdCDWJMSV64uRnEg.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1400\" \/>\n\t<meta property=\"og:image:height\" content=\"606\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Micha\u0142 Lot\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.evertop.pl\/#organization\",\"name\":\"Evertop\",\"url\":\"https:\/\/www.evertop.pl\/\",\"sameAs\":[\"https:\/\/www.facebook.com\/EvertopPoland\/\",\"https:\/\/www.linkedin.com\/company\/evertop-software-development\/\"],\"logo\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.evertop.pl\/#logo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/www.evertop.pl\/wp-content\/uploads\/2021\/04\/logo_new.png\",\"contentUrl\":\"https:\/\/www.evertop.pl\/wp-content\/uploads\/2021\/04\/logo_new.png\",\"width\":582,\"height\":114,\"caption\":\"Evertop\"},\"image\":{\"@id\":\"https:\/\/www.evertop.pl\/#logo\"}},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.evertop.pl\/#website\",\"url\":\"https:\/\/www.evertop.pl\/\",\"name\":\"Evertop\",\"description\":\"we code the future\",\"publisher\":{\"@id\":\"https:\/\/www.evertop.pl\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.evertop.pl\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-GD1sSLAdCDWJMSV64uRnEg.png\",\"contentUrl\":\"https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-GD1sSLAdCDWJMSV64uRnEg.png\",\"width\":1400,\"height\":606},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#webpage\",\"url\":\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/\",\"name\":\"How To Write a Simple Downloading App With Flutter - Evertop\",\"isPartOf\":{\"@id\":\"https:\/\/www.evertop.pl\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#primaryimage\"},\"datePublished\":\"2020-04-22T08:15:09+00:00\",\"dateModified\":\"2021-04-25T20:14:28+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Strona g\\u0142\\u00f3wna\",\"item\":\"https:\/\/www.evertop.pl\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How To Write a Simple Downloading App With Flutter\"}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#webpage\"},\"author\":{\"@id\":\"https:\/\/www.evertop.pl\/#\/schema\/person\/c0bb2cdddb3419f7c8a7403ebdb4147f\"},\"headline\":\"How To Write a Simple Downloading App With Flutter\",\"datePublished\":\"2020-04-22T08:15:09+00:00\",\"dateModified\":\"2021-04-25T20:14:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#webpage\"},\"wordCount\":1026,\"publisher\":{\"@id\":\"https:\/\/www.evertop.pl\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-GD1sSLAdCDWJMSV64uRnEg.png\",\"keywords\":[\"downloading files\",\"flutter\",\"mobile\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.evertop.pl\/#\/schema\/person\/c0bb2cdddb3419f7c8a7403ebdb4147f\",\"name\":\"Micha\\u0142 Lot\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.evertop.pl\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/7cbe8049f78e4979ace9619e9effd83e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/7cbe8049f78e4979ace9619e9effd83e?s=96&d=mm&r=g\",\"caption\":\"Micha\\u0142 Lot\"},\"url\":\"https:\/\/www.evertop.pl\/en\/author\/mlot\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How To Write a Simple Downloading App With Flutter - Evertop","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/","og_locale":"en_US","og_type":"article","og_title":"How To Write a Simple Downloading App With Flutter - Evertop","og_description":"Intro In this article you will learn how to write a simple app which: downloads a file, shows download progress, stores downloaded file available outside the app, shows local notification with a download result, opens downloaded file in a native app by tapping the notification. If you are new to Flutter and you have never [&hellip;]","og_url":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/","og_site_name":"Evertop","article_publisher":"https:\/\/www.facebook.com\/EvertopPoland\/","article_published_time":"2020-04-22T08:15:09+00:00","article_modified_time":"2021-04-25T20:14:28+00:00","og_image":[{"width":1400,"height":606,"url":"https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-GD1sSLAdCDWJMSV64uRnEg.png","path":"\/home\/evertop\/web-evertop\/wp-content\/uploads\/2020\/09\/1-GD1sSLAdCDWJMSV64uRnEg.png","size":"full","id":1701,"alt":"","pixels":848400,"type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Written by":"Micha\u0142 Lot","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Organization","@id":"https:\/\/www.evertop.pl\/#organization","name":"Evertop","url":"https:\/\/www.evertop.pl\/","sameAs":["https:\/\/www.facebook.com\/EvertopPoland\/","https:\/\/www.linkedin.com\/company\/evertop-software-development\/"],"logo":{"@type":"ImageObject","@id":"https:\/\/www.evertop.pl\/#logo","inLanguage":"en-US","url":"https:\/\/www.evertop.pl\/wp-content\/uploads\/2021\/04\/logo_new.png","contentUrl":"https:\/\/www.evertop.pl\/wp-content\/uploads\/2021\/04\/logo_new.png","width":582,"height":114,"caption":"Evertop"},"image":{"@id":"https:\/\/www.evertop.pl\/#logo"}},{"@type":"WebSite","@id":"https:\/\/www.evertop.pl\/#website","url":"https:\/\/www.evertop.pl\/","name":"Evertop","description":"we code the future","publisher":{"@id":"https:\/\/www.evertop.pl\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.evertop.pl\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#primaryimage","inLanguage":"en-US","url":"https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-GD1sSLAdCDWJMSV64uRnEg.png","contentUrl":"https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-GD1sSLAdCDWJMSV64uRnEg.png","width":1400,"height":606},{"@type":"WebPage","@id":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#webpage","url":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/","name":"How To Write a Simple Downloading App With Flutter - Evertop","isPartOf":{"@id":"https:\/\/www.evertop.pl\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#primaryimage"},"datePublished":"2020-04-22T08:15:09+00:00","dateModified":"2021-04-25T20:14:28+00:00","breadcrumb":{"@id":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Strona g\u0142\u00f3wna","item":"https:\/\/www.evertop.pl\/en\/"},{"@type":"ListItem","position":2,"name":"How To Write a Simple Downloading App With Flutter"}]},{"@type":"Article","@id":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#article","isPartOf":{"@id":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#webpage"},"author":{"@id":"https:\/\/www.evertop.pl\/#\/schema\/person\/c0bb2cdddb3419f7c8a7403ebdb4147f"},"headline":"How To Write a Simple Downloading App With Flutter","datePublished":"2020-04-22T08:15:09+00:00","dateModified":"2021-04-25T20:14:28+00:00","mainEntityOfPage":{"@id":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#webpage"},"wordCount":1026,"publisher":{"@id":"https:\/\/www.evertop.pl\/#organization"},"image":{"@id":"https:\/\/www.evertop.pl\/en\/how-to-write-a-simple-downloading-app-with-flutter\/#primaryimage"},"thumbnailUrl":"https:\/\/www.evertop.pl\/wp-content\/uploads\/2020\/09\/1-GD1sSLAdCDWJMSV64uRnEg.png","keywords":["downloading files","flutter","mobile"],"articleSection":["Blog"],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.evertop.pl\/#\/schema\/person\/c0bb2cdddb3419f7c8a7403ebdb4147f","name":"Micha\u0142 Lot","image":{"@type":"ImageObject","@id":"https:\/\/www.evertop.pl\/#personlogo","inLanguage":"en-US","url":"https:\/\/secure.gravatar.com\/avatar\/7cbe8049f78e4979ace9619e9effd83e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7cbe8049f78e4979ace9619e9effd83e?s=96&d=mm&r=g","caption":"Micha\u0142 Lot"},"url":"https:\/\/www.evertop.pl\/en\/author\/mlot\/"}]}},"_links":{"self":[{"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/posts\/1858"}],"collection":[{"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/users\/22"}],"replies":[{"embeddable":true,"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/comments?post=1858"}],"version-history":[{"count":6,"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/posts\/1858\/revisions"}],"predecessor-version":[{"id":4341,"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/posts\/1858\/revisions\/4341"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/media\/1701"}],"wp:attachment":[{"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/media?parent=1858"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/categories?post=1858"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.evertop.pl\/en\/wp-json\/wp\/v2\/tags?post=1858"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}