Flutter
Parse SDK (REST)
Flutter应用中使用Parse SDK保存和读取文件的技术指南
12 分
从 flutter 应用程序保存文件 介绍 有时应用程序需要存储的数据通常太大,无法存储在 parseobject 内。最常见的用例是存储图像,但您也可以将其用于文档、视频、音乐和其他二进制数据。 要在 parse 上存储文件,您应该始终将文件与另一个数据对象关联,以便在查询对象时可以检索此文件路径。如果您不进行关联,文件将被存储,但您将无法在 cloud 上找到它们。 另一个重要提示是给文件一个具有文件扩展名的名称。此扩展名使 parse 能够确定文件类型并相应处理。我们还应该提到,每次上传都会获得一个唯一标识符,因此使用相同名称上传多个文件没有问题。 在 flutter 中,parsefile 和 parsewebfile 让您能够在 cloud 中存储和检索应用程序文件。本指南解释了如何在您的 flutter 应用程序中存储和检索文件,以管理 back4app 云存储。 如果您不将文件与数据对象关联,文件将成为孤儿文件,您将无法在 back4app cloud 上找到它。 前提条件 一个应用 https //www back4app com/docs/get started/new parse app 在 back4app 上 注意 请遵循 https //www back4app com/docs/get started/new parse app 以了解如何在 back4app 上创建 parse 应用。 一个连接到 back4app 的 flutter 应用。 注意 请遵循 https //www back4app com/docs/flutter/parse sdk/parse flutter sdk 以创建一个连接到 back4app 的 flutter 项目。 一台运行 android 或 ios 的设备(或虚拟设备)。 为了运行本指南示例,您应该正确设置插件 https //pub dev/packages/image picker 。不要忘记为 ios 添加权限,以便访问存储在设备中的图像。{ btn target=” blank” rel=”nofollow”}。仔细阅读设置 android 和 ios 项目的说明。 目标 创建一个 flutter 画廊应用,上传并显示来自 back4app 的图像。 1 理解 parsefile 和 parsewebfile 类 在这个 flutter 的 parse sdk 中有三种不同的文件类 parsefilebase parsefilebase 是一个抽象类,是该 sdk 可以处理的每个文件类的基础。 parsefile parsefile 扩展了 parsefilebase parsefilebase ,并默认在每个平台上用作文件类(不适用于网页)。这个类使用来自 file file 的原始文件存储。 dart\ io dart\ io parsewebfile parsewebfile 相当于在 flutter web 中使用的 parsefile parsefile 。这个类使用一个 uint8list uint8list 来存储原始文件。 可用于在 parsefilebase parsefilebase 上操作文件的方法: save() save() 或 upload() upload() 用于将文件保存到云端 download() download() 用于检索文件并存储在本地存储中 从保存的文件中获取信息的属性有: url url 获取文件的 url。只有在您保存文件或从 parse object 获取文件后,才可用。 name name 获取文件名。这是用户在调用 save() save() 方法之前提供的文件名。在调用该方法后,该属性会接收一个唯一标识符。 2 上传图像 要上传图像,您只需创建一个 parsefilebase parsefilebase 实例,然后调用 save save 方法。 让我们在我们的 upload upload 函数中做到这一点: 1 parsefilebase? parsefile; 2 3 if (kisweb) { 4 //flutter web 5 parsefile = parsewebfile( 6 await pickedfile! readasbytes(), 7 name 'image jpg'); //name for file is required 8 } else { 9 //flutter mobile/desktop 10 parsefile = parsefile(file(pickedfile! path)); 11 } 12 await parsefile save(); 上述代码片段创建并保存了图像,保存完成后,我们将其与一个 parseobject parseobject 关联,名为 gallery gallery 1 final gallery = parseobject('gallery') 2 set('file', parsefile); 3 await gallery save(); 3 显示图像 要显示图像,您需要获取图像的 url。 要上传图像,您只需创建一个 parsefilebase parsefilebase 实例,然后调用 save save 方法。 1 parsefilebase? varfile = parseobject get\<parsefilebase>('file'); 2 3 return image network( 4 varfile! url!, 5 width 200, 6 height 200, 7 fit boxfit fitheight, 8 ); 4 从 flutter 应用上传和检索 现在让我们使用我们的示例在 flutter 应用中上传和显示图像,界面简单。 打开你的 flutter 项目,去到 main dart main dart 文件,清理所有代码,并用以下内容替换它: 1 import 'dart\ io'; 2 3 import 'package\ flutter/cupertino dart'; 4 import 'package\ flutter/foundation dart'; 5 import 'package\ flutter/material dart'; 6 import 'package\ image picker/image picker dart'; 7 import 'package\ parse server sdk flutter/parse server sdk dart'; 8 9 void main() async { 10 widgetsflutterbinding ensureinitialized(); 11 12 final keyapplicationid = 'your app id here'; 13 final keyclientkey = 'your client key here'; 14 15 final keyparseserverurl = 'https //parseapi back4app com'; 16 17 await parse() initialize(keyapplicationid, keyparseserverurl, 18 clientkey keyclientkey, debug true); 19 20 runapp(materialapp( 21 title 'flutter storage file', 22 debugshowcheckedmodebanner false, 23 home homepage(), 24 )); 25 } 26 27 class homepage extends statefulwidget { 28 @override 29 homepagestate createstate() => homepagestate(); 30 } 31 32 class homepagestate extends state\<homepage> { 33 pickedfile? pickedfile; 34 35 list\<parseobject> results = \<parseobject>\[]; 36 double selecteddistance = 3000; 37 38 @override 39 widget build(buildcontext context) { 40 return scaffold( 41 body padding( 42 padding const edgeinsets all(16 0), 43 child column( 44 crossaxisalignment crossaxisalignment stretch, 45 children \[ 46 container( 47 height 200, 48 child image network( 49 'https //blog back4app com/wp content/uploads/2017/11/logo b4a 1 768x175 1 png'), 50 ), 51 sizedbox( 52 height 16, 53 ), 54 center( 55 child const text('flutter on back4app save file', 56 style textstyle(fontsize 18, fontweight fontweight bold)), 57 ), 58 sizedbox( 59 height 16, 60 ), 61 container( 62 height 50, 63 child elevatedbutton( 64 child text('upload file'), 65 style elevatedbutton stylefrom(primary colors blue), 66 onpressed () { 67 navigator push( 68 context, 69 materialpageroute(builder (context) => savepage()), 70 ); 71 }, 72 ), 73 ), 74 sizedbox( 75 height 8, 76 ), 77 container( 78 height 50, 79 child elevatedbutton( 80 child text('display file'), 81 style elevatedbutton stylefrom(primary colors blue), 82 onpressed () { 83 navigator push( 84 context, 85 materialpageroute(builder (context) => displaypage()), 86 ); 87 }, 88 )) 89 ], 90 ), 91 )); 92 } 93 } 94 95 class savepage extends statefulwidget { 96 @override 97 savepagestate createstate() => savepagestate(); 98 } 99 100 class savepagestate extends state\<savepage> { 101 pickedfile? pickedfile; 102 bool isloading = false; 103 104 @override 105 widget build(buildcontext context) { 106 return scaffold( 107 appbar appbar( 108 title text('upload fie'), 109 ), 110 body padding( 111 padding const edgeinsets all(12 0), 112 child column( 113 crossaxisalignment crossaxisalignment stretch, 114 children \[ 115 sizedbox(height 16), 116 gesturedetector( 117 child pickedfile != null 118 ? container( 119 width 250, 120 height 250, 121 decoration 122 boxdecoration(border border all(color colors blue)), 123 child kisweb 124 ? image network(pickedfile! path) 125 image file(file(pickedfile! path))) 126 container( 127 width 250, 128 height 250, 129 decoration 130 boxdecoration(border border all(color colors blue)), 131 child center( 132 child text('click here to pick image from gallery'), 133 ), 134 ), 135 ontap () async { 136 pickedfile? image = 137 await imagepicker() getimage(source imagesource gallery); 138 139 if (image != null) { 140 setstate(() { 141 pickedfile = image; 142 }); 143 } 144 }, 145 ), 146 sizedbox(height 16), 147 container( 148 height 50, 149 child elevatedbutton( 150 child text('upload file'), 151 style elevatedbutton stylefrom(primary colors blue), 152 onpressed isloading || pickedfile == null 153 ? null 154 () async { 155 setstate(() { 156 isloading = true; 157 }); 158 parsefilebase? parsefile; 159 160 if (kisweb) { 161 //flutter web 162 parsefile = parsewebfile( 163 await pickedfile! readasbytes(), 164 name 'image jpg'); //name for file is required 165 } else { 166 //flutter mobile/desktop 167 parsefile = parsefile(file(pickedfile! path)); 168 } 169 await parsefile save(); 170 171 final gallery = parseobject('gallery') 172 set('file', parsefile); 173 await gallery save(); 174 175 setstate(() { 176 isloading = false; 177 pickedfile = null; 178 }); 179 180 scaffoldmessenger of(context) 181 removecurrentsnackbar() 182 showsnackbar(snackbar( 183 content text( 184 'save file with success on back4app', 185 style textstyle( 186 color colors white, 187 ), 188 ), 189 duration duration(seconds 3), 190 backgroundcolor colors blue, 191 )); 192 }, 193 )) 194 ], 195 ), 196 ), 197 ); 198 } 199 } 200 201 class displaypage extends statefulwidget { 202 @override 203 displaypagestate createstate() => displaypagestate(); 204 } 205 206 class displaypagestate extends state\<displaypage> { 207 @override 208 widget build(buildcontext context) { 209 return scaffold( 210 appbar appbar( 211 title text("display gallery"), 212 ), 213 body futurebuilder\<list\<parseobject>>( 214 future getgallerylist(), 215 builder (context, snapshot) { 216 switch (snapshot connectionstate) { 217 case connectionstate none 218 case connectionstate waiting 219 return center( 220 child container( 221 width 100, 222 height 100, 223 child circularprogressindicator()), 224 ); 225 default 226 if (snapshot haserror) { 227 return center( 228 child text("error "), 229 ); 230 } else { 231 return listview\ builder( 232 padding const edgeinsets only(top 8), 233 itemcount snapshot data! length, 234 itembuilder (context, index) { 235 //web/mobile/desktop 236 parsefilebase? varfile = 237 snapshot data!\[index] get\<parsefilebase>('file'); 238 239 //only ios/android/desktop 240 / 241 parsefile? varfile = 242 snapshot data!\[index] get\<parsefile>('file'); 243 / 244 return image network( 245 varfile! url!, 246 width 200, 247 height 200, 248 fit boxfit fitheight, 249 ); 250 }); 251 } 252 } 253 }), 254 ); 255 } 256 257 future\<list\<parseobject>> getgallerylist() async { 258 querybuilder\<parseobject> querypublisher = 259 querybuilder\<parseobject>(parseobject('gallery')) 260 orderbyascending('createdat'); 261 final parseresponse apiresponse = await querypublisher query(); 262 263 if (apiresponse success && apiresponse results != null) { 264 return apiresponse results as list\<parseobject>; 265 } else { 266 return \[]; 267 } 268 } 269 } 找到您的 应用程序id 应用程序id 和 客户端密钥 客户端密钥 凭据,导航到您的应用程序仪表板 >设置 >安全性和密钥,网址为 https //www back4app com/ 在 main dart main dart 中更新您的代码,包含您项目的 应用程序id 应用程序id 和 客户端密钥 客户端密钥 在 back4app 中 keyapplicationid = 应用id 应用id keyclientkey = 客户端密钥 客户端密钥 运行项目,应用程序将如图所示加载 结论 此时,您已经在 back4app 上上传了图像,并在 flutter 应用程序中显示了它