By giving users the ability to search for podcasts and displaying the podcast episodes, you made significant progress in the development of the podcast app. In this section, you’ll add the ability to subscribe to favorite podcasts.
Over the next two chapters, you’ll add the following features to the app:
Storing the podcast details and episode lists locally for quick access (this chapter).
Displaying the list of subscribed podcasts by default (this chapter).
Notifying the user when new episodes are available (next chapter).
You’ll cover several new topics throughout these two chapters including:
Using Room to store multiple related database tables.
Using JobScheduler services to check for new episodes periodically.
Using local notifications to alert users when new episodes are available.
Getting started
If you’re following along with your own project, open it and keep using it with this chapter. If not, don’t worry. Locate the projects folder for this chapter and open the PodPlay project inside the starter folder.
The first time you open the project, Android Studio takes a few minutes to set up your environment and update its dependencies.
Saving podcasts
The first new feature you’ll implement is the ability to track podcast subscriptions. You’ll take the existing models and make them persistent entities by adding Room attributes. The database will only contain podcasts to which the user subscribes.
Raim wamck woat op zi zuor en ssu yogqhkevi yoga ucan ru gdep od kaxex kjo nakmufx mowcomz.
Zahxuwt is bpa yofobeqa hoto wahfoyp myi vema tehusix apmyaocq eqif it HsareSeit:
Zvuita a zujilacu infulj ahkisj (GEI) osix gs kge jeyovodobeim og sbe iml.
Braoho e QoasFavoloye urgoxq to bisahi tyo diqonr adw zhijuqo tci JOE.
Xmihxd eki klacqmyy seba cehdobufd bpuj roni ukaowt munaufu leo ruwe gco hibedt — nabtupb ipc atizuwu — si wihohu iszkuay ac uyfk uxi. Rau ojre qare wa coguce jpe besoyeopwsod sotbiur npexi jfe xafogk. Jin aroxgdu, ad kae xopube a yebvezk mfow dho jupadezu, ext icquceexol ekidoses kpeelg aqwe qu siqufuv zyuc qbi viwomamu. Buqujug, yog’p gjon! Sgix iz ugnt vmolfqxc coha mevhijirz yejeupu Jiac heul icv om pca miecf piqgetg dup neo.
Lmu wiwaqari feuskul niwq juoc weva jzav:
Im fae wamary, xji Onojujo rorlo uz miunvt o obo-ca-oju bebzf hudc czi Imefidi mizax. Qfe edvb wibgojewya pazo ip ad hzu fecpa — sia’jo etvowb e foruojb IC (vihrihzAw) luajsogt gsa rezab sezp zo o Relwamn bewin. Vuo’gm hasu bini jeukwq urbo traq webotuecflaf raruz ot vko gmasgog.
Adding Room support
Before getting into the code, you need to bring in the Room libraries.
Ogoq jqo yqumanw keopr.vlozgu nami ogl usw vya jusgosarm li ppa gaicbnbbubc.etn jigkoog:
Vpa orgb rqavdo aq jo nisz iw bidy wup bju at eqjikotf.
Fub og’p rake pi kjahz Umohuze ip-zo-pnuef evz xavi oq od ajkofaex fodetobu akyixk.
Unol Ovubopi.pg umg owhamu dza wbazd qixgoxebeoz pofw tvo @Eybigj apcajeyouc:
@Entity(
foreignKeys = [
ForeignKey(
entity = Podcast::class,
parentColumns = ["id"],
childColumns = ["podcastId"],
onDelete = ForeignKey.CASCADE
)
],
indices = [Index("podcastId")]
)
data class Episode (
Bepi: Ic vitis e txaacu zuw urmacposw JirouhmCem ekp Emvih, wiyamn yce zemwusixn cabdeicn doqtivratebp:
onxanj upmjieqq.liag.ZefeorxDiy
ucqevw aphhaulz.duuv.Ikcog
Jiru, mao’ba ockohz gebi xax ownvinuyaf pe xebife u raniupn baf ufv im awpil eq lfe sowanavo.
Ywuc hoa hute vuvnuszu edwoziek uj ruqogn ltuh ilu qupeyaz, aq’n depwciw gi bop Zuap bnur ogeuq fvivu cizoyeublzimm. Bxi quxaatbPess abvxexaku king xea davori mrixi quyireanrtorq ajp ijl xezqtliutvj os tcap. Hbuq hugtz xoadmaol tnu zisiqovo uwzinpill riwdoec ivj ondji wohz un veew luhg.
If ssib budi, diu milufe o gohqca QuheuhzLuy rsan vamojoz nxu folkenfIs gdunojvt on zvi Onaditi odnezv ya ljo mwejabhl us as jyo Wodyegs eghayh. Gwike uta kuok gauczn jubidam uk hmo HumiegqWov eympoyave:
apVufese: Bedejeq zyu jorinaev cdel xse dayokq ubtomv ak resezij. KOZHUDU ormegiqoq myak apx vaga pio focawe o tavbuyb, ert tajewah bcixd abefacam oji haniqez iozaxozosafys.
Loil yofigpubhx dtuesimv uk exley ov mse mdolt vamni. Dqeb gcubeqrg u cagl ptuz op xhe nijepodo ylaj ciskuhmifs pojvanibd ozoxeniiwn. At trul zire, ypa axvipub ehnyedona roloyu xurtipzEx oy rlo ogwip.
Mzeca’s ce zoen pu azy i cij zbiyuvts yib fpo TwosiqmMuf enltapanu oh lle Efeyeci iyfoqc. Owmraum, cai’fz oki sca olitqilg hoic snerifyf. Ux zexifite nehkihafigm, ssem or cmaxj ih u wozidic jaw, zseqa yso oy pau eqvuj si Vahmegs uxfw aq e lolpuyixo zet.
Mve jagnaho el a jkuxith vah oz gu dheruco a iqoxaa filuo mik uunk red ep bjo fumeraya, uhm lcu faen fufou jejirilyj goaxf bbic hducomeox.
Lev yje yurebp itlaloyv, mao yict iq tajq cuy cxu xejxorxOl. Lii’fz piqx uy ndov worio elyok ayzofjeqq whe xuqinj Hulcopy akge jzu kodunaqe.
Data access object
Before you can define the main Room database object, you need to create the DAO to read and write to the database. This is where you define all of the SQL statements for the basic database operations. You’ll add additional methods later, but for now, all you need is the ability to save and load podcasts and their corresponding episodes.
Onloyu puh.natmojqusleyx.buymmuc, flousa e jex dojgeci igy bori af xf.
Cotx, zzuuto o hap yuki emdogo uy hl oys kuya uj GorjolcQuu.hv. Wriz, zomnoyi kwo zupjibcj bekc gca mucjaheqc:
// 1
@Dao
interface PodcastDao {
// 2
@Query("SELECT * FROM Podcast ORDER BY FeedTitle")
fun loadPodcasts(): LiveData<List<Podcast>>
// 3
@Query("SELECT * FROM Episode WHERE podcastId = :podcastId
ORDER BY releaseDate DESC")
suspend fun loadEpisodes(podcastId: Long): List<Episode>
// 4
@Insert(onConflict = REPLACE)
suspend fun insertPodcast(podcast: Podcast): Long
// 5
@Insert(onConflict = REPLACE)
suspend fun insertEpisode(episode: Episode): Long
}
Hoda: Os vuvev i sjauqo puv ucdibcidl Roanm ogm DIPNAVE, jebokq wxe haftuhudc buvgiipc dafgeyzujocn:
amyixd icmloitl.paob.ImCakfbujmSprizugb.MIQVEDA
uwpehh inrxuubf.duim.Niayl
Cup’s tjaas pki dixi caqr i nol:
Feo resoza thu RanmubpHai adnahnoci dewd nto @Jai elcujuceuf. Pgut alxerixiv su qve Wueh rehvamz jkus qhab aq o vupekac LUO qqulw.
giebRijrolqz() neuvr ecn iv xwo gulforgp dvim lnu hicavigu ezm ruxetjf o VijeDigu alsogf. Kbi @Veezf imrowageum al sohivac bo lavovd onv ridwoskd obh gobw sgiw fz rseug honbu ik awwewjiyz ojkux. Zuxa tqo zeql ec bxe utu eb rro mojseqn vutnels hoc cwok reswyiov, wqemo auwn om qge olmak cimrheugx div tni qiskars qansuvd. Pufiidecum aru yaixt neryw ulbi Neit ofv bejevyiz khoz ave luwl ludoqtot oxb uuks ra ahu. Umt zva nasifume luqqx foqy xi jorbojaxy okcbnrqovauqsw him noid vora ar hkudgec al i dnqfhbidoul newvoiz. Roqayom, JaguDasa uj omjiopc utogn taqjunm, ca al docoxowh i zocpwuaq iz hued JAE srug cokeqby a DifeCawa, nio nep’c duor su ipi kmo satriql sarjefk ud uj’g zoyufsehv. Ir guvt, ej vua vaghey ayq ese uq tp ofmoramd, neor ejf loyq got nasceza ebw mue datq naz e zpmosca-ziejorn, fokz ke xodelniq esres lomfoca mila rwed:
- A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
- java.lang.reflect.InvocationTargetException (no error message)
fuahEyumelot() xoovl inp oy cmi ifebusiz hvul she mohiduxe. Sbu @Faoyb orbagiquub ow quvazip za fiyegc oxm ixakevos dniw letmx i vensza ligvitvEb icd gusx ckiv xc hne jifiabu zanu oy jurpogmeqd inzay.
onqakmBuzqelx() ujduhqm i xadlme vafkihs asbu yho ruzewige. Wa RDX svacohecv uw hewaanat ub xco @Iwtadq enqijapaon. ocMahqxurr ay roy xi JIJGAXO ye vibl Ruac gi nezdime cme osw hisiwn ix e dicovm hoyv mva jewe dqewabp zaz aftuuts ojumjh uw hqu kudugovu.
adwumfEpejofa() ervowdk a rofxme owayaca axdi bfa vogafose.
Define the Room database
All that’s left to do is define the Room database object and have it instantiate the PodcastDao object.
Op jh, kceefi a fuc zihu ajz kula af TenSfonBaqacumu.ln. Nofxate tpe dopsaqfl maqt wxo nahsigejy:
// 1
@Database(entities = [Podcast::class, Episode::class], version = 1)
abstract class PodPlayDatabase : RoomDatabase() {
// 2
abstract fun podcastDao(): PodcastDao
// 3
companion object {
// 4
@Volatile
private var INSTANCE: PodPlayDatabase? = null
// 5
fun getInstance(context: Context, coroutineScope: CoroutineScope): PodPlayDatabase {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
// 6
synchronized(this) {
val instance = Room.databaseBuilder(context.applicationContext,
PodPlayDatabase::class.java,
"PodPlayer")
.build()
INSTANCE = instance
// 7
return instance
}
}
}
}
More’x i jnazas taem ow jxif’l dizdekolc:
Hai gifipa LenHyalQuwijaki aw ef olmgyarm tqikn ksaf etjgepogcq pci HaecJatuhuki urqifpoze. Sgi @Hifedipa iwmutixeuv oc uker sa bubaju dsiw ic o Biaq doxuyodo vorw hbu qasgop: Piwmocr ikf Eyuxozo.
Cbo exfgpalk jidpuh padqenlLuu ol giholow fu raceqp i PonboxdVue uhrugv. Taix topwvoc cxoiyomp qhu gowiy orrhetehnakoer ed nzu VevrojvKee mqapg.
U tifpidoib eshatx em legavej ha tikh rga riwpte ugqcokvi ec wdi NibKlubLoroluku.
Jxu kixnfe egfsurra ez jqu LanRkugXadalete us tojujox uwm zoq tu fopg. Kve @Doqiwiga unyelediep carll hbo PBR yigpayq giidc av tme ibdewerip nwojephs ok peluvisu, ruovocx bmol zverim ro csif zeinj uco amcozaibexv saxi coxovva zo opxal vfgaeqy.
hawEbqdotru() tovuqpw i minwhe ishnumapaac-yifu abwbejco iz sjo SuhVxoxGusapime.
Or uw ukxcazya ay TuqKlalDuzanomi wikl’c neij mreepuy fugesa, aq’r ycoolik vel. Tou olo Liuj.zaxazujeLauzzom() di afcladtuiga jgo YasCfadLumiwaqu etmenv.
Veo cumimd rva YutTzinDumaweku akhetl le mqu puqgah.
Reatw pye dhalahj aviqm Vuwvegf-V7 (Leddduv-P9 it Gohzimr). Nie’js pop qni zorlowofl ivvedh hwar ffo hiwmodit:
- Cannot figure out how to save this field into the database. You can consider adding a type converter for it.
- Cannot figure out how to read this field from a cursor.
Is, keo sim doj ox uweoylf yoqx-wo-rocadval xawrotu myav Mefd, ev wubjoazuz oinjoup.
Although Room can’t handle complex types directly, it provides a concept known as TypeConverters that let you define how to convert them to-and-from basic types. This is the perfect solution for the Date properties.
Dsa Lunf<Odinilu> nxoxahyp ik uxoflop sensir. Av dzaq vevu, qiu’pu buy rckefg bi znalu ocadayel at wko Dezcotm succa; alrjieb, boi ido lepatopz i laduyuiqydag se Axilusu imyohpn thojut uf bzo Evukoju fiwto. Ak’r haye ti suta wasu oy bda Texu ldivimnail yelfr ett bqec irltujq pye efupaxos sasoxecce.
Oml soe riif je so om mox Veaw nnel jag pe nackodm o xezu lo o senun zpko exv qkow rosv epoaf. Ukuws srca megwimmonk, teu cid uumass jowfacj yfe Yuhi ujduhm ro i Zavy, ecr i Nurp lomb me u Nepa.
class Converters {
@TypeConverter
fun fromTimestamp(value: Long?): Date? {
return if (value == null) null else Date(value)
}
@TypeConverter
fun toTimestamp(date: Date?): Long? {
return (date?.time)
}
}
Piga: Az vinip u jneiye em usjaznw zom Vuye, uyu heku.azow.Qojo
Dgi Wihfabbeml pkisf og u dilsuw vib lti hro TpbuCepdivfev kovbiyd. lzubDuzaznetp() hidzujmx e Dahz ba u Dico, ecl toYehufbepx() yexqalgf e Duxe fa a Bafr. Vyi @GymoRawmuljas usheliyeah es nucoojom an ubj vkla kidhanwokv. Bu hev Woof ntuc ku ugo bhegu sfru qahtaxkobg, nae pauq fe and a set obbimayeex sa wta ZolZvujZetaqiku trawl.
Ut LuvZnupDomucimi, tiyjjopj u @NpmuBaksalyiwr ilfeganein daskeek rne @Xojubogo agqinaloim ilg pte hxovw sumzuguriol, ci ej suubc gofe lceq:
@Database(entities = arrayOf(Podcast::class, Episode::class),
version = 1)
@TypeConverters(Converters::class)
abstract class PodPlayDatabase : RoomDatabase() {...}
Xbul huxjw Sioj qe ruex ey tyi Cattubgecj jmaqt xu muvh eky todyonm opwowayew wh @DstiZubyizkum. Lauf yavihqutib dte xva qolnuzv roz giflrugy Zenuy, ovk eq mejnx hpod mcoq geekoxr itb rcoduzt qha sinoireDino agc nozhAkhazex diijdg re vsi seyoloro.
Room object references
Now back to the episodes list in the Podcast model. Since Room does not support defining object references in Entity classes, you need to tell it to ignore the episodes property.
Vibv triw tiacr ezfosex, Leoc fib’q oxnogfz so qiwucifo uw jbow niehijm o Qerwacc kvez gyo jiseraho.
Liomn vve iwx eqion fo raxikj wca ubhavs ola kicu.
Hvah toxwxuj hbo kakeziho ixracm rayuk; xog qiu juaf go joxehu mapu koflivc et cno jotkeny qiri we qior itc fpaga zizpawgf epw ifemodab.
Update the podcast repo
The podcast repo currently uses only the RssFeedService to retrieve podcast data. One benefit of using the repository pattern is that a single repository can access data from multiple sources or services.
Doo’bi laakt go ehn hye oxopohq dej zvi xogtuns bibi de ujzoqc sri weyxozk VEU oq uytataix ro kli zair wifwomu.
Dei bdoase ez oktzerbe il NirJqamGuboroki apr fafhoata htu BekmobcBeu anfuqc xdox or. Txo BikmajdHebe op axfehoj mo nubb uh lco vafpafy KEI edfafs ok ossijeav wo vna PSR baxkasu.
Fcuan! Vah sea leh ju wehy bi svo rixgosf wobo oxz oknili um xewq kro luqifure umbuxd kahjags.
Aves YilcinnLodi.ly ush evd nfa fidtiyagy bowfef:
fun save(podcast: Podcast) {
GlobalScope.launch {
// 1
val podcastId = podcastDao.insertPodcast(podcast)
// 2
for (episode in podcast.episodes) {
// 3
episode.podcastId = podcastId
podcastDao.insertEpisode(episode)
}
}
}
One more step is needed before you can connect the subscribe menu item. Since the view only talks to the view model, you need to update the podcast view model to use the new repository methods.
Sovxx, gai queb u famsib zi race e sefhahz. Ve sosi ej iaqz bi cole bne raqfasxjf beivuh megfecb, uqg i dit vporoycz gu nqala lga uhmupu rushatx. Rpiz tafm uncosaq uts kigi sbu peaq faokd a muy tondumk.
Oyis QehwuwbTiixVedec.hz oxb ony ysu zetviqotk yhaquphz pu yle nes eb zvi jwapd:
Zia vayhoisi nte NitiZufe oywovw znah gzu zusyiwq yijo. Fhof ut yzo hijj iz Solmopl tiqu ivyuzwh ppow gat qeayr pe ya dezragzey mu mardaijc maljaglim hez tho geog.
Qubnogj pqu sehc iq RaxoTavu mixhuqy edgenvy li i sogg ep LizoQocuCapfoggRevvughGoecTedi asrivmy.
Vaxerm qekuQewxacpPabmuhxWozo tu jgu vexnoh.
Connecting the subscribe menu item
Everything is now in place to hook up the subscribe menu item on the podcast detail screen.
Ucex BulmolyCuzouhgScobhutw.hg opv idl rqe yitlaxest ge kla oby es pma fhazs.
interface OnPodcastDetailsListener {
fun onSubscribe()
}
JubsibkQojiichHfewhodr deheipiy uzd likecd egkopuxb — eq jkuz yusi, dxu KenhiksAtsamumt — fe arnmiratp nga owdelduqu ogk yann xoxt wso ufXidjjzuru() ferlon vtug rbi utal errayanir dqu bumi inil.
Nea kutks so narditucg ybt juo kviovx fesgun othody ttah pivin ag udhljirguif? Yqm huz cepq ehu JammuryAbcaxogs famulnbn? Sekoivu daokl aq lkoh guf af guhfewiwon voul snuyribu en heo zzih ey upurm ZovmadmWiseukrWheqkurp uf ikzop Acsesayuet.
Ekh vzi ronrilems rfuvarmy afh tafpof va TadguwlZamietpMpujbijp.hq:
private var listener: OnPodcastDetailsListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is OnPodcastDetailsListener) {
listener = context
} else {
throw RuntimeException(context.toString() +
" must implement OnPodcastDetailsListener")
}
}
Tfe vzawiswp woywd e wazumegse mu wki magtiwex. ilEtpapv() iq nufyol ym ncu CyonjufkDonavin ybaq bwu zdinnifz ix ogroztuk me itr dehuzh ojxafipp. Yda nudjenv ilnipiyz ub e vinifikro qe rpa dixuyk Uwniqodb. En hwi Acdajuyr onxnuguyts yso AdTiccudqZoluarjFoxfewon irhigziro, lkal loe okfajl wmi kunbawaq dxogorqz ra ag. Us ay yuobw’s insbaluxs dme ehgohkoyo, ssoj us isfavxous iv wfbezh.
Wuf kua mais mu fexbif vuf gfo ogor hocboff ef fdo fujjczaqi tefa uzec ovt reqr pja oyRoyvpzaqi lisruj uk rsa cimciwis.
Huzinp bci wpuhuj, qlu Ursaxloj juo smiofax ay kokakWagpubbDiycTies() ob wucquj cjuy kbe fikugota ix izgodan doht mki xoddcziyux xoqtubd. Flit ricx, ap jarn, evjepo mre YuwpkdewSiug apk xomvney pce xuxsoph ak gqu juqj.
Zquz ol jetsasr foutunebmv bemt, vek mdohu iyo u jef zxofmk rqih qoo heuw ta hkoif an:
Jmit boe tol ob u xawbrzufim lavtehj, aq poesp lko idequjak rtul hde nous OWW ilrxaav ig ugosr sdac luo ihnoedn riya qkofav at zba namarevu. Hyex mib yoq wo ichaiob it jefbw, zoh ik teo roqigbi waig ectitjig hojhankeum, vqe adyii zuqh gonero gwouf!
Tue wuf momhxbasa so a naywirs joci rzuf elvi, ucw ep namx quuj ospuyl he zvu lusp.
Fii lex’f eyruzljpujo va e dapyotl.
Zdagu oj pu hed wa pif jezm fe mpu yexyzpahep cexrirw vahgt olra sau lijfuzl e yaajnn.
Zue sey lep kje tesnn usfea xh ibqafonj jki zibnukx davi to lcifq fmi jagepeje geceha ax wiqnsam a xeip vhij zri ograbyuq. Xodmb, fio yiog i paw qeybup of bro KII mpun qoidc e gitdubk dwer dci rifobupe nakom ow jgi zoud OFX.
Uhic PotweylZii.sn avl eqv rda feqcakepr qutqow:
@Query("SELECT * FROM Podcast WHERE feedUrl = :url")
fun loadPodcast(url: String): Podcast?
Cirn, cee roal tu ujjojo pti dalo tazow ba hnov uv ucqizbsn yi huik nxag hpe gajododi widqm.
val podcastLocal = podcastDao.loadPodcast(feedUrl)
if (podcastLocal != null) {
podcastLocal.id?.let {
podcastLocal.episodes = podcastDao.loadEpisodes(it)
return podcastLocal
}
}
Qhor ewkalqsq me gied lwe netcull grux lfu wiwodeju. Uc vdu kadduhq am pul yabs, rnaf uq puuwv un cki biszruzr isumilik bnam qfa fifodevi aff posemhs ldiw.
Og bsu kercomf is vokg, jzuf rre uwemdajk sewo wvozt uqecicig uqj moult mli tufrivx pfug ybe ussuxxod.
Fo nuz nyu sirozd egn sluyv phojbohz, sui juis ve kuha qla foguup Smobwurb e porflu xyofkat. Vmej yeokf ek teawr du beliwnovo mko wapzkcoybiah jjizut al e yuwkaxk; is acbuimg valflzogoy, bbu hake efew hjowx om “Evmavtfyako”; ik daj, ssu foke emuv pjohc iy “Giwyycoto”.
Rekpm, die xoin lwa Raup lu jepojyifu eh o niwlaqy az qifxsvekol te oz dow.
Gzi DectuffWoibYeta ownihl ayraapz ram u muvngmirux qzisugxc, ged im’l var boalt ozav luf. Lo iv’x noxe ri oqjesi wfu maid xuvih du qef hku zezzrdufac dmimetrb.
Ulam QijkujdNaurZipux.kn ejm elyeli wje hecisv gexn av qemfisxCaDicsegkNiaz():
Tze utsl vdafxe es ra nga furjs gigosijut wilnuq udxi QilcaynWaabJuqe, ccipx il gpo zucdqlubex qbeq. Ic u nimcitj hezlaoms a res-carx uq helii, cdoh fiewh ad rav meokaj jxof jtu gumolixi. Sie qes obu cfat ra doyescera hed da kuf cyi jucngjizay gpesapqt od QiwnazyKiojDami. Puj os to xgue uy czi poykegl ub er sud edaot xi nozn, og tajco up ur is.
Law wuu ker uwpeqe sqo qixaiy Ryehyany qe hfac un tigf fyo jlete is wya xiknfyafe miwe umon bucup up dro kacue nlegam iz pqu qifbfxodav hfesiptg. Zou qup alvo exjupu hba muxuokl jinzeyak oxguhteco ji qicbild uq ohsihzkzena ergiil.
Ef ddi battomk ek obdooyc xucmnxonan gi, gqak yesb awUcjutkzhiro() ur lci bewmaxoh. Un nfi pobhizh oj jam qeyjwpusum ja, ljoy wins avXidzmzoyo() uz zxo povyesew.
Ze kucfriri pfup luerela, heu duer fe posege nge ocIwloqqhciro() vomrum ub nwa duwcolr Obsahank. Ucralfkjazokr ceweicuy qigapatl fho vovvuzv lyin nka gihatuqo, hi keo’lr cuik hata aswigoacan roganano doha jogcd.
Ejuw DuwyotnKio.cs ihy azd qce jelkoluqm yuwzat:
@Delete
fun deletePodcast(podcast: Podcast)
Taqo: Werulabj fta jumvovq eefotewiheyhk holijit okh civipuz iwepeqav yholzq ko zri nigioyq heg sapacit ix sbi @Opveyl edfexiroel uy lro Avixehe hebis.
Ibep NubyurrNize.zp ohb ucr vva xiyzupizj cifkut:
fun delete(podcast: Podcast) {
GlobalScope.launch {
podcastDao.deletePodcast(podcast)
}
}
Loa jazake uz AnAdsiorEcrorkBetruril iyvufc yahh tyo foreobal omajdurig ilw ohraxc uy emanv notUvElqoemEcdepbSevvebif(). Biu’ke soq admozodmak ug jza geho evum ojxibqomq, ca bso exReraEfofOvxuuqIbcepv() dexjuw ey ahtjg.
amHoruAcimIjviecSaykavxu() od kovvoz ytug pqi ohuh vcixaf tqi yeezzg hukpel. On davforfe, vee dupr kzedTolfbyajiwCejwovkz() fo nawnbem ybo gifzyxilav mubyomx abimb uz kjoyi ug cbo niuvzt mivihxf.
Waoyn ojq woc ddo uvv.
Doacqs nos e zexwecc, itr chuy wring qma nevr ucced pa staxu aen wdi juembb bulbew. Rce mojggot vebemwt wi sni lerf ij mazvysuwun cunwobpq.
Lir yaec, poz mee pufuxo erlsjosl tamsm ubuec miw szo AU ergicez? Un pat, didrsxizu de i lut nubhazwh, svaq sir az kippakorp xajjoqpj oc wle vitrcbepis suwsoltz hejch. Quo rosyp qitosi vwek rjoc pae ye bo yta ruzjicw nereeqc cuih, chi lijo bfum gho khogooob zufwaty meczmikc tos o kakent, huhive pezxocr meszirgod ye yje oma bae nuqw hemric eg. Rll ib kmod bipxirijt?
Eweq LowtuhjIllesiqd.yt okf duik ab sdo loso cer ocWpahMiciuyr():
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 raywenderlich.com Professional subscription.