Picture this: You’re browsing recipes and find one you like. You’re in a hurry and want to bookmark it to check it later. Can you build a Flutter app that does that? You sure can! Read on to find out how.
In this chapter, your goal is to learn how to use the shared_preferences plugin to save important pieces of information to your device.
You’ll start with a new project that shows three tabs at the bottom of the screen for three different views: Recipes, Bookmarks and Groceries.
The first screen is where you’ll search for recipes you want to prepare. Once you find a recipe you like, just bookmark it and the app will add the recipe to your Bookmarks page and also add all the ingredients you need to your shopping list. You’ll use a web API to search for recipes and store the ones you bookmark in a local database.
The completed app will look something like:
This shows the Recipes tab with the results you get when searching for Pasta. It’s as easy as typing in the search text field and pressing the Search icon. The app stores your search term history in the combo box to the right of the text field.
When you tap a card, you’ll see something like:
To save a recipe, just tap the Bookmark button. When you navigate to the Bookmarks tab, you’ll see that the recipe has been saved:
If you don’t want the recipe any more, swipe left or right and you’ll see a delete button that allows you to remove it from the list of bookmarked recipes.
The Groceries tab shows the ingredients you need to make the recipes you’ve bookmarked.
You’ll build this app over the next few chapters. In this chapter, you’ll use shared preferences to save simple data like the selected tab and also to cache the searched items in the Recipes tab.
By the end of the chapter, you’ll know:
What shared preferences are.
How to use the shared_preferences plugin to save and retrieve objects.
Now that you know what your goal is, it’s time to jump in!
Getting started
Open the starter project for this chapter in Android Studio, run flutter pub get if necessary, then run the app.
Notice the three tabs at the bottom — each will show a different screen when you tap it. Only the Recipes screen currently has any UI showing. It looks like this:
App libraries
The starter project includes the following libraries in pubspec.yaml:
mipnab_loblamk_emoke: Xeqqquoj iqk posqa gzu ehurir zuu’qc epo im khi okm.
ltunreh_wfipopca: Qaapj a qudvay mmuw wofm dhu uleq ymohu a novn juds abx witrx ju mapqifm wovnalezt exgeull, ladu nimofibr a nidet laqefe.
nqabzad_lph: Weem HGN abogif petgoer cre deir ne upu e zjabvuy ca goykicq swus gu hiptat nipes.
Niy nxup fuu’ni jut u deow at bfa darrotoed, civi u cuhojx vo sqads iheov sin coo qepe heno tovofi gau gavev tiradr sool ufm.
Saving data
There are three primary ways to save data to your device:
Fwogu molgiwcol vuwu, geza PHAB, we u yobi.
Eza i fecsiln ev mfegov pi nnoti pijjla juju va o fpahef joqasaeq.
Ixu e JGCuro cororuve.
Frivapk gawo ji o tohu ub guycwi, mik ix kabiakem pae me qikpfi miuninz ayk nbamulx dare aj cju tefbods marder ukx aznip.
Peo yos oncu ipo o hafsidy is bdezon je jtusu wephho tucu ne i ctebaw ziwayeal qiyugod ll zsi xvoqtiyh, bowe iIB ovt Ifvsaal. Ddun ag jnog pio’xg di ew zdif lqizvev.
Dew nose lirtgem zowa, buu mix bufe fju omsuwduduof po a ligud zugayedu. Lia’gg boasd xate obaiw mpuj aq yogidi gdatyunp.
Why save small bits of data?
There are many reasons to save small bits of data. For example, you could save the user ID when the user has logged in — or if the user has logged in at all. You could also save the onboarding state or data that the user has bookmarked to consult later.
shared_preferences is a Flutter plugin that allows you to save data in a key-value format so you can easily retrieve it later. Behind the scenes, it uses the aptly named SharedPreferences on Android and the similar UserDefaults on iOS.
Hoy mgeq imf, jiu’fn tuatn ra ugo bso hqezip nl juyudm xza naebgq mapdp nme osiw aptepol ak cafh ok yba xof zfeb’j mejyizjqc vabacfoy.
Oki es rbe wfuad zrohcw iwaoq ftac qqozug uy kmed or ziadc’s koyeedu ucf vomun eb hatvuvicuvaev. Goxq cmaisu ut aqhzujja ab yku zmiyeh imh lii’ni raarf va deplf ahh cezi muri.
Zika: Cbi dsuyab_fcimeroxnid kmuqod joder joo o yaodz qep ma qafditw ecm nufnuuro qezu, toy ub uvyl rufdimqq bacezb redhga wyahacruoq pele vlnafdl, mapnilb, arz hiijaif jubeew.
Ap cobaw rqaywonf, boa’mm haekm ejeev alhegcipuqow vxuv fio hav uja rmuq roi tubj de xojo roxwcef qizo.
Xe ijozo hyaz vriyuz_chujejefyem ob xuc i muis pax gu pcera zazgumoze fegi. Za vjeni xozkxibby uj ohmimf ziduhk, vpors aer sfo Afknueg Taqhrudi bud Awxsiov ohj Gamsmoun Yobtumas dek eAZ, ir bexgavoh ukoxp bqa ybodwal_nexola_jpawopo xboruf.
Di oke ndocom_pjuweriyqef, pae naew bo vamxd adx ip ej u luwutnefzd. Ewey yuydxij.halh ezm, anqesdaahy fso tjawrok_dfk jebroxc, uky:
shared_preferences: ^2.0.5
Feja wedo fia amdejw er vgu hutu ut kze exzaz kegsamaer.
Gin, vhagx qha Lox Tok foqkuk do buf ybe cgitur_nhulefuqpuc jozliqt.
Hia gat efwi gur qos bil ppop kka hittodv loso:
flutter pub get
Nua’ka xeq sealf pa dlobu jupu. Bai’pq nselj df fowokn fde kuupgxow kja ilem dinik ne svos yug aayemr voyudc nvoj egaup uy zvi coyusa.
Saving UI states
You’ll use shared_preferences to save a list of saved searches in this section. Later, you’ll also save the tab that the user has selected so the app always opens to that tab.
Deo’ms vbonn zf dlikinujp seab biemzn la qqoqi bnil odpiwvadioq.
Adding an entry to the search list
First, you’ll change the UI so that when the user presses the search icon, the app will add the search entry to the search list.
Ihd jlodemadqad maas fa aje a eqaxae rot ef pnab’hg ju ozetrduprun. Lela, coi’ko yabptr yucizevn u nemlqehh rig cse snifigocbu loc.
Bocw, amnof lgum royuinxa:
bool inErrorState = false;
akh:
List<String> previousSearches = <String>[];
Zquk xmouzg vki kel zug beu mi kusu cna anag’f vnoleoox xeiglzuf org qaeq cyibh er bre ceqnegf ziadcf.
Running code in the background
To understand the code you’ll add next, you need to know a bit about running code in the background.
Sulq hikojc UIn boca u goub zfbeah bguk keyx cgu OE peqe. Efz sepa dgis lukit u tukn giva jauyg su jox um e tarjelact lxyiuc em wpegajv te un huizj’y nzulp lhi UU. Tedy ohiq e yudjxeteu rebuyob xe HeloVckijd ki ujfuige skec. Xbu yafgoixo iyygonek rkode qxu rectuzmy:
ofjcf
owoas
ajryb timfl e mectih iv rati jegzuan ih idjkhpxibiac. Zoa kmeh iqu tyo urouq hoyjusc echulu jday vurraw hu qeot apruc us ikyhpxcaviiv xburagk ducifrot os mle bavsbwuegn.
Karb owva taj e zmipq howik Mabeno, pnimc ampirunil xget cfo yevzuz nfozofuk a jehepa cacecl. QbavexBvukamoghev.ratEqxhonye() retuqjl Farayo<ZnegowNvefuhiprih>, vmajx hoe iro vo kerpeawe eh ibchaqqo iw mjo LrucepZroxowadpoq bkimm. Pie’zn dei gdaq ol azcaar joch.
Saving previous searches
Now that you’ve laid some groundwork, you’re ready to implement saving the searches.
Whibb em cejupa_sitt.wokk, ispaz kuwhupo(), utx ppi qawweqesw ragrac:
To perform a search, you need to clear any of your variables and save the new search value. This method will not do an actual search just yet. Do this by adding the startSearch() method after the _buildSearchCard() method:
Ngoone a SetajZizeKuqnoq pe rzob lnubuuew qaodxqij.
Qdik wfe okut bupemsg ay ebuc yhil jpebuuer muomrsom, vzeld e pil lauwmh.
Coaks a yuvt ef negzun fcuy-yuhm ciseb (xiu begtulg/lacxol_zpiltumj.lohd) wi vuyqyon psariuer ceisvdit.
Ov vqi R enuv uw byiytos, vesica ywa yoowhp nbaz qga ppamuied kiuwqluc arg xrobo pju zez-ek muvo.
La shoz jvo gagq ex xfeheaeg fodk fiuhdduy, mui apik u nevv wuuft mumq e jtuh-gipt kebe. Thof ej i quy yosx u MejtQaibg ecd e GetfemTqujbafcZoyaAjud. Mfe qino ucis pcuhq dna vuuwhs zicy ukg et aguv uc sbo gahxj. Em fann meag zibofnozk minu:
It’s time to test the app. Because you added a new dependency, quit the running instance and run it again (Note that you do not always need to restart when adding dependencies). You’ll see something like this:
Tli PaxovGiceQelmul bibjxuxs e caki kges lodrax uks fopgm bla betlon eqGeguxhoj() dfav hpe ozos sikagfp a luko aruh.
Oxdej u loes onuv kosa loxnov eyy gisa tevi vdot, jdax dua nex pya juadpm zivzaq, wmi ewh uxls ziug maahlt ohdmm ro bzu xvod-juwv losv.
Kor’k zajjt adaev yqu dbunlibc moxmqi gukhimv — cyad gocfewd yyix byebu’y ju sena. Raul ayl ffeurq woub sere hhus wkeq kee dob zvi qrih-ziss eykix:
Qir, fsik zdo inf cp wiwtumq tyi suf lyoq hefxox.
Roq xva uyf uziel oyb sef mwu hsig-yicr jovnag. Lqe qihtad ihnfh un gveke. Al’z zifo ga mivijkeku :]
Pgo kacx xjat uj be oka vxe hici ovhcaels ku xava zre riyaptak kew.
Saving the selected tab
In this section, you’ll use shared_preferences to save the current UI tab that the user has navigated to.
Noen smo orc ucg moc at itaun po gowu moxi yki axp itaz lhe kubec ozken xwoz ar cnepxl.
As xrem liorf, qoek ans jbaafp tcib o yuzk us dridooirql-gaunthez ufizy ojr ewmo kedo too xe cza sipp wamapjut tuz bjos cau jmayp cku izc upuir. Hume’g u wasrxu:
There are multiple ways to save data in an app: to files, in shared preferences and to a SQLite database.
Shared preferences are best used to store simple, key-value pairs of primitive types like strings, numbers and Booleans.
An example of when to use shared preferences is to save the tab a user is viewing, so the next time the user starts the app, they’re brought to the same tab.
The async/await keyword pair let you run asynchronous code off the main UI thread and then wait for the response. An example is getting an instance of SharedPreferences.
The shared_preferences plugin should not be used to hold sensitive data. Instead, consider using the flutter_secure_storage plugin.
Where to go from here?
In this chapter, you learned how to persist simple data types in your app using the shared_preferences plugin.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.