Flutter
...
Data Objects
Implementasi Parse dengan Flutter: Tipe Data dan Penyimpanan
19 mnt
panduan ini memperkenalkan tipe data parse di flutter, menggunakan contoh dari file main dart penyimpanan data parse berputar di sekitar parseobject, yang berisi pasangan kunci nilai dari data yang kompatibel dengan json, menjadikannya tanpa skema ini berarti anda dapat menyimpan data apa pun tanpa mendefinisikan skema terlebih dahulu anda dapat mengatur pasangan kunci nilai apa pun yang anda inginkan, dan backend kami akan menyimpannya sebagai contoh, katakanlah anda sedang melacak skor tinggi untuk sebuah permainan sebuah parse object tunggal dapat berisi kami sarankan anda nameyourclasseslikethis dan nameyourkeyslikethis untuk meningkatkan keterbacaan dan pemeliharaan kode memahami aplikasi kami untuk lebih memahami back4app, mari kita eksplorasi contoh kode dari operasi parse dalam aplikasi flutter dengan tipe data utama yang didukung panduan ini tidak akan menjelaskan kode aplikasi flutter karena fokus utamanya adalah menggunakan parse dengan flutter prasyarat untuk menyelesaikan tutorial ini, anda akan membutuhkan android studio https //developer android com/studio atau vs code terinstal (dengan plugin dart dan flutter) sebuah aplikasi dibuat di back4app catatan ikuti tutorial aplikasi parse baru untuk belajar cara membuat aplikasi parse di back4app sebuah aplikasi flutter yang terhubung ke back4app catatan ikuti instal parse sdk di proyek flutter untuk membuat proyek flutter yang terhubung ke back4app sebuah perangkat (atau perangkat virtual) yang menjalankan android atau ios 1 bekerja dengan objek parse setiap parseobject memiliki nama kelas (misalnya, gamepoint) yang digunakan untuk membedakan berbagai jenis data berikut adalah cara anda dapat membuat dan menyimpan objek parse baru dengan jenis data string , int , & boolean final gamepoint = parseobject('gamepoint') set('score', 1337) set('playername', 'sean plott') set('cheatmode', false); await gamepoint save(); untuk mengquery objek parse baru dan mengambil tipe data final querybuilder\<parseobject> querygamepoints = querybuilder\<parseobject>(parseobject('gamepoint')); final parseresponse response = await querygamepoints query(); if (response success && response results != null) { for (var gamepoint in response results!) { final score = gamepoint get\<int>('score'); final playername = gamepoint get\<string>('playername'); final cheatmode = gamepoint get\<bool>('cheatmode'); } 2 penghitung anda dapat menambah atau mengurangi field integer dalam parseobject menggunakan metode set() namun, ini tidak efektif dan dapat menyebabkan masalah jika beberapa klien mencoba memperbarui penghitung yang sama parse menyediakan dua metode yang secara otomatis menambah dan mengurangi bidang angka untuk menyimpan data tipe penghitung setincrement() setdecrement() pembaruan untuk menambah nilai penghitung int akan ditulis sebagai final gamepoint = parseobject('gamepoint') objectid = 'yourobjectid' setincrement('intfield', 1); await gamepoint save(); untuk mengurangi final gamepoint = parseobject('gamepoint') objectid = 'yourobjectid' setdecrement('intfield', 1); await gamepoint save(); menggunakan setincrement() dan setdecrement() dengan panggilan save() memungkinkan anda untuk memperbarui nilai sebagai bagian dari operasi penyimpanan yang lebih besar di mana anda mungkin memodifikasi beberapa bidang ini lebih baik untuk menghindari permintaan jaringan tambahan 3 daftar parse menyediakan metode untuk bekerja dengan data daftar, termasuk setadd , setaddunique , setremove , dan versi all mereka daftar \["a","b","c"] 3 1 setadd final gamepoint = parseobject('gamepoint') objectid = 'yourobjectid' setadd('liststringfield', 'd'); await gamepoint save(); hasil \["a","b","c","d"] 3 2 setaddall final gamepoint = parseobject('gamepoint') objectid = 'yourobjectid' setaddall('liststringfield', \['e','f']); await gamepoint save(); final gamepoint = parseobject('gamepoint') objectid = 'yourobjectid' setaddall('liststringfield', \['e','f']); await gamepoint save(); final gamepoint = parseobject('gamepoint') objectid = 'yourobjectid' setaddall('liststringfield', \['e','f']); await gamepoint save(); final gamepoint = parseobject('gamepoint') objectid = 'yourobjectid' setaddall('liststringfield', \['e','f']); await gamepoint save(); hasil \["a","b","c","d","e","f"] setaddall tidak menambahkan elemen duplikat jika daftar sudah mengandungnya 3 3 setaddunique final gamepoint = parseobject('gamepoint') objectid = 'yourobjectid' setaddunique('liststringfield', \['a', 'e', 'g']); await gamepoint save(); hasil \["a","b","c","d","e","f","g"] 3 4 setremove final gamepoint = parseobject('gamepoint') objectid = 'yourobjectid' setremove('liststringfield', 'd'); await gamepoint save(); hasil \["a","b","c","e","f","g"] 4 hapus field dari parseobject anda dapat menghapus satu field dari sebuah objek dengan menggunakan operasi unset final gamepoint = parseobject('gamepoint') objectid = 'yourobjectid' unset("liststringfield"); 5 berkas parsefile memungkinkan anda untuk menyimpan dan mengambil berkas aplikasi di cloud di bawah ini adalah contoh dasar mengunggah berkas gambar lokal ke back4app // create parsefile object final parsefile = parsefile(file(image path)); final response = await parsefile save(); if (response success) { print('file uploaded successfully ${parsefile url}'); // save this file in an object final gamepoint = parseobject('gamepoint') set('title', 'post with an image') set('imagefile', parsefile); // saving the file as a field final postresponse = await gamepoint save(); } potongan kode ini menunjukkan cara mengambil berkas gambar final query = querybuilder\<parseobject>(parseobject('gamepoint')); final response = await query query(); if (response success && response results != null) { for (var gamepoint in response results!) { parsefilebase? varfile = gamepoint get\<parsefilebase>('file'); if (varfile != null) { final fileurl = varfile url; print('game title image url $fileurl'); } else { print('no file found for this object '); } } } mulai dari parse server 5 2 3 ada perubahan yang dapat menyebabkan kesalahan saat mencoba mengunggah berkas ikuti panduan ini https //www back4app com/docs/platform/parse server version#o cil untuk memperbaiki masalah unggah yang mungkin anda alami panduan selanjutnya akan membahas lebih lanjut dan menunjukkan template tentang bagaimana menyimpan dan menampilkan file dengan parse https //www back4app com/docs/flutter/parse sdk/flutter save file 6 geopoint parse memungkinkan anda untuk mengaitkan koordinat lintang dan bujur dunia nyata dengan objek menggunakan tipe data geopoint menambahkan parsegeopoint ke parseobject akan memungkinkan kueri untuk mempertimbangkan kedekatan objek dengan titik referensi contoh // request permission here and get the current location the `position` object // create geopoint object final geopoint = parsegeopoint(latitude position latitude, longitude position longitude); // create an object with the geopoint final gamepoint = parseobject('gamepoint') set('name', 'current location') set('location', geopoint); // save the geopoint in a field final response = await gamepoint save(); anda dapat menemukan contoh mandiri untuk menyimpan lokasi geopoint dalam main dart https //github com/templates back4app/flutter datatypes/blob/18c4c372eb49c1cd950eeaac355564134a5e70c4/lib/src/main dart file contoh aplikasi penuh contoh ini menunjukkan bagaimana untuk buat, hapus, dan perbarui sebuah gamepoint objek parse tangani berbagai jenis data, termasuk string, double, boolean, file, geopoint, daftar, dan tanggal di ios, anda perlu memberikan izin akses yang diperlukan kepada simulator anda ios menyediakan panduan pengembang tentang sumber daya yang dilindungi aplikasi contoh dalam panduan ini akan memerlukan lokasi https //developer apple com/documentation/bundleresources/information property list/nslocationwheninuseusagedescription dan foto https //developer apple com/documentation/bundleresources/information property list/nsphotolibraryaddusagedescription kunci izin yang ditemukan dalam panduan itu untuk berfungsi tambahkan kunci tersebut ke dalam info plist file, yang terletak di /ios/runner/info plist anda dapat melewati langkah di atas jika anda menjalankan aplikasi flutter anda di web import 'dart\ async'; import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk flutter dart'; import 'package\ image picker/image picker dart'; import 'package\ flutter/foundation dart'; import 'dart\ io'; void main() async { widgetsflutterbinding ensureinitialized(); const keyparseapplicationid = 'your application id'; const keyparseclientkey = 'your client key'; const keyparseserverurl = 'https //parseapi back4app com'; await parse() initialize( keyparseapplicationid, keyparseserverurl, clientkey keyparseclientkey, autosendsessionid true, debug true, ); runapp(const myapp()); } class myapp extends statelesswidget { const myapp({super key}); @override widget build(buildcontext context) { return materialapp( title 'datatypes', theme themedata( primaryswatch colors blue, ), home const myhomepage(), ); } } class myhomepage extends statefulwidget { const myhomepage({super key}); @override myhomepagestate createstate() => myhomepagestate(); } class myhomepagestate extends state\<myhomepage> { final texteditingcontroller stringcontroller = texteditingcontroller(); final texteditingcontroller doublecontroller = texteditingcontroller(); final texteditingcontroller liststringcontroller = texteditingcontroller(); final texteditingcontroller listintcontroller = texteditingcontroller(); final texteditingcontroller pointercontroller = texteditingcontroller(); final texteditingcontroller objectidcontroller = texteditingcontroller(); final texteditingcontroller uniquevaluecontroller = texteditingcontroller(); final texteditingcontroller removevaluecontroller = texteditingcontroller(); bool boolvalue = false; datetime selecteddate = datetime now(); final string responsemessage = ''; xfile? pickedfile; bool isloading = false; @override widget build(buildcontext context) { return scaffold( appbar appbar( title const text('datatypes'), ), body padding( padding const edgeinsets all(16 0), child singlechildscrollview( child column( crossaxisalignment crossaxisalignment start, children \<widget>\[ buildtextfield('string field', stringcontroller), const sizedbox(height 20), buildtextfield('double field', doublecontroller, isnumeric true), const sizedbox(height 20), buildswitch('bool field', boolvalue, (value) { setstate(() { boolvalue = value; }); }), const sizedbox(height 20), textbutton( onpressed () => selectdate(context), child text( 'select date ${ selecteddate tolocal()}' split(' ')\[0]), ), const sizedbox(height 20), buildtextfield( 'list string field (comma separated)', liststringcontroller), const sizedbox(height 20), buildtextfield( 'list int field (comma separated)', listintcontroller), const sizedbox(height 20), buildtextfield('pointer field (object id)', pointercontroller), const sizedbox(height 20), buildimagepicker(), const sizedbox(height 20), elevatedbutton( onpressed savedata, child const text('save'), ), const sizedbox(height 20), elevatedbutton( onpressed () async { await deletedata( objectidcontroller text); // await dummyfunction(); }, child const text('delete'), ), const sizedbox(height 20), buildtextfield( 'object id to delete or update', objectidcontroller), elevatedbutton( onpressed () async { await updatedata( objectidcontroller text); }, child const text('update'), ), const sizedbox(height 20), buildincrementdecrementbuttons(), const sizedbox(height 20), buildlistoperations(), const sizedbox(height 20), text( responsemessage), ], ), ), ), ); } widget buildtextfield(string label, texteditingcontroller controller, {bool isnumeric = false}) { return textfield( controller controller, keyboardtype isnumeric ? textinputtype number textinputtype text, decoration inputdecoration( border const outlineinputborder(), labeltext label, ), ); } widget buildswitch(string label, bool value, function(bool) onchanged) { return switchlisttile( title text(label), value value, onchanged onchanged, ); } widget buildimagepicker() { return gesturedetector( child pickedfile != null ? container( width 250, height 250, decoration boxdecoration(border border all(color colors blue)), child kisweb ? image network(pickedfile! path) image file(file(pickedfile! path)), ) container( width 250, height 250, decoration boxdecoration(border border all(color colors blue)), child const center( child text('click here to pick image from gamepoint')), ), ontap () async { final picker = imagepicker(); xfile? image = (await picker pickimage(source imagesource gallery)); if (image != null) { setstate(() { pickedfile = image; }); } }, ); } widget buildincrementdecrementbuttons() { return row( mainaxisalignment mainaxisalignment spacebetween, children \[ expanded( child elevatedbutton( onpressed () async { await incrementfield( objectidcontroller text); }, child const text('+ double'), ), ), const sizedbox(width 10), // adding some space between buttons expanded( child elevatedbutton( onpressed () async { await decrementfield( objectidcontroller text); }, child const text(' double'), ), ), ], ); } widget buildlistoperations() { return column( children \[ buildtextfield('unique value to add', uniquevaluecontroller), elevatedbutton( onpressed () async { await adduniquetolist( objectidcontroller text, uniquevaluecontroller text); }, child const text('add unique'), ), const sizedbox(height 20), buildtextfield('value to remove', removevaluecontroller), elevatedbutton( onpressed () async { await removefromlist( objectidcontroller text, removevaluecontroller text); }, child const text('remove'), ), ], ); } future\<void> savedata() async { //parse values string stringvalue = stringcontroller text; list\<string> liststringvalue = liststringcontroller text isnotempty ? liststringcontroller text split(',') // split by comma map((e) => e trim()) // remove any surrounding whitespace from each element tolist() \[]; list\<int> listtintvalue = listintcontroller text isnotempty ? listintcontroller text split(',') // split by comma map( (e) => int parse(e trim())) // convert each string to an integer tolist() \[]; double? doublevalue; if ( doublecontroller text isnotempty) { doublevalue = double parse( doublecontroller text); } bool boolvalue = boolvalue; datetime selecteddate = selecteddate; final gamepoint = parseobject('gamepoint') set('bool', boolvalue) set('date', selecteddate); if (stringvalue isnotempty) gamepoint set('string', stringvalue); if (doublevalue != null) gamepoint set('double', doublevalue); if (liststringvalue isnotempty) { gamepoint setaddall('liststring', liststringvalue); } if (listtintvalue isnotempty) gamepoint setaddall('listint', listtintvalue); if ( pointercontroller text isnotempty) { gamepoint set('pointer', parsepointer( pointercontroller text)); } if (pickedfile != null) { setstate(() { isloading = true; }); parsefilebase? parsefile; if (kisweb) { parsefile = parsewebfile(await pickedfile! readasbytes(), name 'file jpg'); } else { parsefile = parsefile(file(pickedfile! path)); } await parsefile save(); gamepoint set('file', parsefile); } var apiresponse = await gamepoint save(); if (apiresponse success && apiresponse results != null) { setstate(() { isloading = false; pickedfile = null; }); scaffoldmessenger of(context) removecurrentsnackbar() showsnackbar(const snackbar( content text( 'file saved successfully on back4app', style textstyle(color colors white), ), duration duration(seconds 3), backgroundcolor colors blue, )); } else { print("this is your request error ${apiresponse error}"); } } future\<void> updatedata(string objectid) async { final gamepoint = parseobject('gamepoint') objectid = objectid; // update fields with new values if ( stringcontroller text isnotempty) { gamepoint set('string', stringcontroller text); } if ( doublecontroller text isnotempty) { gamepoint set('double', double parse( doublecontroller text)); } gamepoint set('bool', boolvalue); gamepoint set('date', selecteddate); if ( liststringcontroller text isnotempty) { list\<string> liststringvalue = liststringcontroller text split(',') map((e) => e trim()) tolist(); gamepoint setaddall('liststring', liststringvalue); } if ( listintcontroller text isnotempty) { list\<int> listintvalue = listintcontroller text split(',') map((e) => int parse(e trim())) tolist(); gamepoint setaddunique('listint', listintvalue); } if ( pointercontroller text isnotempty) { gamepoint set('pointer', parsepointer( pointercontroller text)); } if (pickedfile != null) { parsefilebase? parsefile; if (kisweb) { parsefile = parsewebfile(await pickedfile! readasbytes(), name 'file jpg'); } else { parsefile = parsefile(file(pickedfile! path)); } await parsefile save(); gamepoint set('file', parsefile); } // save the updated object var response = await gamepoint save(); if (response success) { scaffoldmessenger of(context) showsnackbar( const snackbar(content text('data updated successfully!')), ); } else { scaffoldmessenger of(context) showsnackbar( snackbar( content text('error updating data ${response error! message}')), ); } } future\<void> incrementfield(string objectid) async { final gamepoint = parseobject('gamepoint') objectid = objectid setincrement('double', 1); await gamepoint save(); } future\<void> decrementfield(string objectid) async { final gamepoint = parseobject('gamepoint') objectid = objectid setdecrement('double', 1); await gamepoint save(); } future\<void> adduniquetolist(string objectid, string value) async { final gamepoint = parseobject('gamepoint') objectid = objectid setaddunique('liststring', value); await gamepoint save(); } future\<void> removefromlist(string objectid, string value) async { final gamepoint = parseobject('gamepoint') objectid = objectid setremove('liststring', value); await gamepoint save(); } future\<void> selectdate(buildcontext context) async { final datetime? picked = await showdatepicker( context context, initialdate selecteddate, firstdate datetime(2000), lastdate datetime(2101), ); if (picked != null && picked != selecteddate) { setstate(() { selecteddate = picked; }); } } future\<void> deletedata(string objectid) async { // delete data logic final parseobject = parseobject('gamepoint') objectid = objectid unset("liststring"); await parseobject save(); } // convert pointer field to a suitable format parseobject parsepointer(string objectid) { // there should be an existing game class with objects final pointer = parseobject('game') objectid = objectid; return pointer; } } kode ini menginisialisasi parse sdk di flutter, menyiapkan aplikasi utama, dan menampilkan halaman beranda sederhana dengan judul kesimpulan dalam panduan ini, anda belajar tentang parseobjects dan berbagai tipe data yang tersedia untuk parse anda juga belajar bagaimana menangani operasi seperti menyimpan dan mengambil tipe data ke dan dari backend back4app anda