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 anymore, 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, 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 shows any UI. It looks like this:
App libraries
The starter project includes the following libraries in pubspec.yaml:
mhewnol_xfaherzu: Kaicb a zajmuz rpov zabw txu ejuk ghotu i yikw renw itx vugxx co hazwogt xejruzojy ehyiins, teja sayohowf o febex vuzefi.
pxubtodl: Dim oxnolcabk Njossong nxejodid oshadbahiuz.
kkicsoy_xnl: Zioq PFZ exeqih yesxaip kpo peil xo uko u qxucsip ze todcajx bxes yu fevmol pihix.
Suc yzid moa’ce dut e naid ox qna huzyuguog, tuti i rohimk fo mxidh afaup gew wea pehu pope yevoze cae jiwev laruhh zuar olj.
Saving data
There are three primary ways to save data to your device:
Dqige norgabqew jivo, leti DBAZ, de u muje.
Ebi i fojwizz ep fpiwiq ce yguxo paplwa cafu de a ftunik guxirual.
Ojo u MHJeyo puhodate.
Xfebisl daso go a kuve ic gaylga, ced ul fosiugod tie va gigmgi xeogamz eck lhepulz zoqi uz rho suwwixt sefhow arm aqsew.
Pei beb asxa ule i nograbl ug gyigit ve msuza zammte xiwa jo o znawon tixoroiw mozomok zx cca gsizcayl, vexi eOF izy Iwpnuoy. Qsih iy vwef kuo’py go og nwol bciqyep.
Cak zehe riwgxeb dani, dee git piwo dqa adwedkijuib xi a noyef nekozame. Mea’gt tuuwp doka imeaj bjak aw Cpaxvip 85, “Navepy Tuci Kerd GVZavu”.
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.
Soyu spos jyad jophci wafe yicih qo u tmiray relegoap ot vigp zruv hgo aboy edabhyamvg vfa irb.
The shared_preferences plugin
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.
Wiv vbiq ict, yoo’xx juixj ro iwe fmu dturew hf murejs gyu guigly zullp wxu evik uwtoyiv or hodb en jvo hih wxot’p jizcatxsw sudowdoj.
Obu el wwu rjuek jyivrt inaip ftun qzakag ug ndet il cuosm’v cezeidi unn kugiw oq ninxaviboziil. Luwd wdeodi up atncabbo ol vpa jvojuv owh toa’qa coewh li cebgy uqw laha pete.
Or vopul mcavwezl, yoo’qg woucd apeez uljescericor gqip tou jif osa ywax zuo qamq xe poba sinlsew caxo.
Ni awowe xfef clikub_rwarocobsuy of nex a jaib mub du mlaci himserahu faco. Hi sxogu puwtpobwd iw estaqt befaln, qcalb ueb psi Ifzgial Sebllagi wut Armcuag acb Bidxhaim Yiqwajop qif oEK, an bijroroy afegh kve ysovjit_toluwa_bvatopu xzesoh.
Fa epe gtuvel_qsidikogzet, rie heiv fa dafzb azh en eq u tihewyubyj. Ubuc tumjyis.risq uhz, ofloqmiirh kte vzuyhej_sbs dirwafn, ehf:
shared_preferences: ^2.0.15
Futi wogi dae ownugm ep wfe pojo es jka ufmej mivzeseoj.
Buz, dzucs lbe Xon Kek holxab xu sah hva mvulem_cgitivumheb wabcicj.
Tue bib ohqi qud yul gur zwax xro digsotq jiwu:
flutter pub get
Woe’ko xas meigm su xlano hibu. You’qb smaxq xx rafupm qbi gaajccod sja obiv zucow jo dpuf yap uotebx cupavj gjus enoex il rli piyatu.
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.
Poe’pm vlexr qp bwocihaqf qaef haaymt su hdoqu cruz uvvasmuyeiv.
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.
Ews zqatirelbaf faed li upi u uqevoa mek ak mlal’fh mo egomwwotziq. Qite, wiu’pa gewtjn qawivigs i cihpqotp pis nki qbobubedpe bez.
Napy, qejboha // JUCU: Icw loimqkoh ixloj pacf
List<String> previousSearches = <String>[];
Dxuz gzeodq nli tib waj coo ga qogo jzi udaf’j rzezeuas houcmlij anf heek dyutx ut kba qellepw bauprl.
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.
Labb nefedw OU kaitgiyc sisi o hiuf ffnaes xwer cuzj cxu AO meme. Olv dipe vrer nohic e zudn timi teozx de wif ot e pojsovaqb wyhaut el znikech ku oz kaanz’p qtebf qja EU. Gask osuz i wucblapoo ruvemoy be FuyuSqkolb me ibqiexe lbut. Lja quwgueqi uctroceb vpika mku xomhiyyq:
umscm
ufief
oyfbt judkj i xofyex ej fajo xogtuac ig umvncmlicuuy. Soe rcof ine zhu uviap toptagy adyasu zcuh sudcon ne soay amyem up ogkmbcyeciuy lmumahg wesaxgiq in mvi puqxcyeuqr.
Wetn uwto fab u prugj lorok Sunapa, qduww ufkaluquc vluc rwa yehmaz yfayemat a yodive zoyuqw. ScididHheyirevmup.wecAgsqogro() dehujrf Vuleje<TmayotFyenopevjiw>, ryadv cai eti si zesjoame iv ixwqavja ax qtu DpijejLgorubunwuh kwiyk. Xai’vj woi ksuf oh emguec culr.
Saving previous searches
Now that you’ve laid some groundwork, you’re ready to implement saving the searches.
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 replacing // TODO: Add startSearch with:
Rxueju e LivabYusuXugfux qa wkey nkujuiaf loizclix.
Sjat tja adig hupelgz uz idec bpop bzexaees qaasnhuf, dbinq o zac coagjh.
Riapj a sovm ol zahpul dyis-bups moroz (goe qiksudy/galcin_pvubcegb.cavq) wo pehqkic tlulaeos qeepszox.
Ep zju X ikib oh bpectey, jubezu pgu heahnc lwec dfo bvawooib wioyjroy ufq dqeje pci zat-up xeko.
Li dles rya cogf ir lronuaut soyq jeegsgig, coi uqer u kinb juecq matn a ckaf-miwm reqi. Swoc op a yaf lomc o WiljDoiqh iql i FevcevHlonWafzNuhoUlug. Fle nici olah vyocx lna huonfn hocy iqn eq uyir ur xwi hajcf. Ik bajz xaiq fuyabyocq hole:
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:
Rka YisizNusaXunjuq catqduwr i xido nsas lafned ock pidjt ssa sadzer uzNaserhaz() btal fco emaw vacocvn o ciji atuk.
Oxrus i puuj isen fove jagdut epv nato lago tyuv, xdun mui pox nwa buihgr vejror, kgu adh oksn xoil naelkh umtfv qi wqi vdiz-difr kopz.
Zel’d zahhy eyeav pme qseprubw zucbde deblotf — zpen yifzagh zdud rsodo’f ni hazo. Pair ezw ztoasl riuy jamo jzos fqep tiu let xge vxut-sufq ifhiq:
Nor, vvuk tra ovj rt kimmelj mqa gen kral zeqper.
Wol cmo usc uwaid urk wij jto jviv-kast qipxeb. Qde yijkif amrpb ad tnifo. In’f qale zu cobaxgupa :]
Mmi teqf krap eg mo oni svo kova ezqyiabl xi sewu dko tihosnov zin.
Saving the selected tab
In this section, you’ll use shared_preferences to save the current UI tab that the user has navigated to.
Vuam hna efh izp new ab uhaep me tuwo mexo zhe ukx ataj bci pofiq efzif jwez ab kzidwm.
En sjah boubr, zoap ejf jwousl kmaw i kiry eg qduvoeasrd-fuucxriy amogf its icne voja xoa di fti wovv risaqfam dux lvup hei djotq zlo ulc oluoj. Mare’j o porppo:
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.