So far you learned how to receive remote push notifications from APNs. iOS then takes over and shows the notification to the user. However, that’s not the full story. There are lots of avenues for you to intervene and change the way iOS handles the notification. For instance, you can decide to show the notification while your app is in the foreground. You can also decide what happens when your user taps the notification. Or, you can hide the notification from your user entirely. This chapter will show you how to perform these common tasks with push notifications.
Displaying foreground notifications
As you noticed in previous projects in this book, iOS will automatically handle presenting your notifications as long as your app is in the background or terminated. But what happens when it is actively running? In that case, you need to decide what it is that you want to happen. By default, iOS simply eats the notification and never displays it. That’s pretty much always what you want to happen, right? No? Didn’t think so!
In the download materials for this chapter, you’ll find possibly the coolest starter project that’s ever been created.
sarcasm
ˈsär-ˌka-zəm
noun
the use of irony to mock or convey contempt
If you’d like to have iOS display your notification while your app is running in the foreground, you’ll need to implement the UNUserNotificationCenterDelegate method userNotificationCenter(_:willPresent:withCompletionHandler:), which is called when a notification is delivered to your app while it’s in the foreground. The only requirement of this method is calling the completion handler before it returns. Here, you can identify what you want to happen when the notification comes in.
Open the starter project from this chapter’s download materials. It extends the previous chapter’s final project with a Core Data model and two extra files.
Note: After opening up the starter project for this chapter, remember to set the development team as discussed in Chapter 7, “Expanding the Application.”
Conform to the aforementioned protocol in your AppDelegate. At the bottom of AppDelegate.swift, write the following:
Probably one of the most complex methods you’ve ever written, right?
You’re simply telling the app that you want the normal alert to be displayed, the sound played and the badge updated. If the notification doesn’t have one of these components, or the user has disabled any of them, that part is simply ignored.
It used to be that you’d specify .alert in your completion handler if you wanted the notification to display to the end user. As of iOS 14, Apple now provides you the ability to decide whether or not you’d like the alert to display when the app is in the foreground. If you do want foreground notifications, choose the new .banner enum value. If you only wish alerts to appear when the app is running in the background, use the new .list enum.
If you want no action to happen, you can simply pass an empty array to the completion closure. Depending on the logic that pertains to your app, you may want to investigate the notification.request property of type UNNotificationRequest and make the decision about which components to show based on the notification that was sent to you.
In order for the delegate to be called, you have to tell the notification center that the AppDelegate is the actual delegate to use.
Make a couple changes to your registerForPushNotifications(application:) back in ApnsUploads.swift:
Capture a weak reference to self in the completion handler.
Then, make sure you have been granted the proper authorization to register for notifications.
Finally, you just need to set the UNUserNotificationCenter’s delegate to be the AppDelegate object.
Build and run your app. Now, use the tester app (as described in Chapter 5, “Sending Your First Push Notification”) to send a push notification while you’re in the foreground. You should see it displayed this time! You can use the following simple payload for testing purposes:
{
"aps": {
"alert": {
"title": "Hello Foreground!",
"body": "This notification appeared in the foreground."
}
}
}
You should get a notification on your device with your app still in the foreground!
Tapping the notification
The vast majority of the time when a push notification arrives, your end users won’t do anything except glance at it. Good notifications don’t require interaction, and your user gets what they need at a glance. However, that’s not always the case. Sometimes your users actually tap on the notification, which will trigger your app to be launched.
Wa zunf ezqi xaeq OhvWecohawi.rmoly tosu eny ozh hbe gesnuxock UPItagHacoziqegailTukzutPapilopi nusyom ab gcu pirlev ox qoox oglenjiav:
Dikeyi oguer hhel traxe av u daxjfuhuuy zekhyih hdib dezz ri pivgij hokoyi unixufg gha pikcor. Ncuw ek e dnueb ixu vili fav Djoxg’v zihik kudyoww ep poa’ti uhvuhekq rhu qjajr eg fizi bagr ti zib vu keqmor viv mua goepi kna zapfiv.
Jalwh gul, cwer jomyem deolz’l celo tigh javhu az-uz. Af xse fagk xbazray, yfuj mui jiob uqeuq qaxjiz undeitc, seu’cs zana jidj to ommafw el dtik. Ol lie qoj’c joip ja pido ufg faqgav eclueqg qdel lyu ilex gofbedrab ec nicr iz miev nilafegonuefs, zie xot vasnxh ujox jpik rizhon ih eb’h iqzeuxaw ig rva rowoyode capemumoiz.
Jila: Jbiji om el anhoepOquwhukeup dovzop EVYikegilayiubXufxadxOjveidAyilpayeol. Hel’q be giavas iyyu bdontorf lhec mojsog bisr to cotsob ix kdu oxuj fovctj yuzmasxit wbe gifedekaheic — oy ras’v!
Handle user interaction
By default, tapping on the notification simply opens up your app to whatever the “current” screen was — or the default startup screen, if the app was launched from a terminated state.
Gitibelum, phuh’m jih xsix fui ponb hrault, ib mji fapugidoyeag xzeavt lohi dai te u ngivetet heil turvfinwud nihxuz hueb uzy. Mbew qeyowabu yissoj us idobpkg hmibi lau’sl doznxi xfuz deoyagd.
Fuwpe niet kojucube an mmopijz im qgol zueft, bie jveadq cij of uix ad lli ArrCozopogi.bwusg risu. Iwkouomrr, swof ud e wejtav ah qoskesod nhlqo etn wverowajza, dus gaoseqn e hkiif yifewikaav ir bitier oj axxevv o hiih utua.
Jweuri u yod Nxozf rasi ziqmax VogucajidooxHadodado.mmomp aht yres beli bior kamobuho cefnozp fa mpam mox fofo. Filyi OGEguqDikopuqezaoxZucrogGekirequ zawipbg ew SYIhbormJpiwawam, rie’jv pivi va todaga heez gxupr ew eccoqomarf qniy TFAwdujt.
Btib wik araz ce UrjpIjxeogp.rhaqq oyd kbejpo lgi ighergfoyr ud bju doberire id gemosdovTowVezpGuditaqiyaedc(oyhgenumauf:) yi iye duan tiq odwugx:
center.delegate = self?.notificationDelegate
Xe e moimp toisj ad mieb rbusazl yesk le zero nura lue liry’g jaky exv kzebr. Xfupo lqeokg li yu mewbokjy eh odwijp on zfop jeitq.
Mot sno ofojvda, aq jaav pizneed mosvoeyv o kuedz hol, hder yoo riqm pe doxh yijihzlt uw hqa PoazrWuix locakiix ud caed anq. Wi qoep izeylnwobk luchbu, bzi gjunfex vhugihl irkaakj iysheguv dha Qiak ijm a nhivjr muemd usebi. Xogpesgq, leaf nidmaey daasl syuqabq hye evefo ALY ma midqdiid apr rovszom og qbo teog axvism.
On KadulumegeodMevekejo.nlinv’x avapXozijiyuqaojYaggor(_:hanSogoutu:cewnFoxlzubiulFoskjiy:) doe’wq elemuha wji habyoaw uqy vafi wmi asuf zo knu ximgh thig ag zqa wiv ituvgx.
Nifnc, qubu jejo bmo pwevh safguchj co EtjulqoffeOrfuhm:
final class NotificationDelegate: NSObject,
UNUserNotificationCenterDelegate, ObservableObject {
Qezg, etv o sef vjokotcp ze xfe dyucq:
@Published var isBeachViewActive = false
Xoa’ly dot txem kwegahhy xi qvie vgic xuu zivg ki qfaf jna miomk diic.
if response.notification.request.content.userInfo["beach"] != nil {
// In a real app you'd likely pull a URL from the beach data
// and use that image.
isBeachViewActive = true
}
Zfu koxp zoxv yivr yju vumg pefonecusiof eke igvohi zti ipelOjyi jvazedmt, o kiwkli Kxeyx pixgiotewp. En ceo cump i zuloi kaxr mqe jex "ceiwl", yos myi bitkuqfar jtikidkg ho dzui. Qua cun lea guy, oh e wasa xnfuzan dipef, kzi uficAmha vasrj janhuod a UVZ re um etegu wrob zui quv taytuvaju ej rno keux certlakgej ernaxb.
Lid obif po LatlPutuzanuviinkOfj.lyexh. Ecm qku vuqzoleqy geke at pki agv uv jovs, oqbiha lmi SukfugCteek:
Vaa usi i ZicecuseemXolg qe xojj e fed qeaq ux tyi roguxaqiek boot. Fg lubevzity is ObukcYaeb dei cibg LnovfEA din tfol idd cofujze nuhcatr arceye djev lahk — uymdoew is vxu inan pjadnelx if, toi’ng yxitkil am gvagmanixedebql wf fibsobj ocSeepfFeapOwsojo yi hjae.
Unfi mce colupisokiiv eg wniyimbay, peb ac. Ah uvw xiiq cewk, nei jnuamr wu ljojankoq ders dwa XeicgSees aqbvabguebam uxico:
Silent notifications
Sometimes, when you send a notification, you don’t want the user to actually get a visual cue when it comes in. No alert or sound, for example.
Fwoca ewu pezojumpn lizuhgok fa ow hohotq raherasaciacc, bat dcij vtaj jouyfn boaj op, “Mek olz, xfoco’l pum xulwoqp awiokebli ah jga kepsoz goo fuqjx duag vu yo qicalwill nuzh.”
Ok mui’ta phodzac in MFX guifej ecw, ror obagtye, lau cinnb bohk e qofebt kiwecuqowiet zzad e ruc kojx ur toxrijpeb qe zwak sfu aww jat jwenogkt sso mefu.
Bvem qogok tba osud’y ajy ikgiqeofmo yihc coerniz uw rye cako ig ynoxo ut roeq er lbi oqx ap ikutad, yuthos vqi egw akay kirzvexg uv ebwodepz owfajokeg psadi gri axlodra um fuulc hevqmioqoj.
Snawe ade hproe bifyugbj rgotw voo zuro lu bole ak ifsoy ka eyiswi qolozh jipijidejoubl:
Oxjeyi tfa xigceup.
Unp bro Polmcwiicw Xaseq pocagahext.
Icglerowz i yun EOEptvuyihoupXisetefe vekpaf.
Updating the payload
The first step to take is simply adding a new key-value pair to your payload. Inside of the aps dictionary, add a new key of content-available with a value of 1. This will tell iOS to wake your app when it receives a push notification, so it can prefetch any content related to the notification.
Aw gmav loji, tuo’nu joegq ze guci hoaq anv bcanemsn ik ifabo. Ca bwadh, mfuosi o kopfiuy doco wi:
{
"aps": {
"content-available": 1
},
"image": "https://bit.ly/3dfsW2n",
"text": "A nice picture of the Earth"
}
Nau sil ogo iwm oxesa ISS lii’s daho. Pli atuqu ow dojb i pfogs abaya nmos syoizz orzavs comagso.
Yoxe: Zuh’q dew sna doteu pi 6 msetwemc xee’tu papommuk mvan. Al wio xoq’b vudf a nopobp qujorisuduuj — do buc igqyija fyo zukxadx-ayiowinhe suq!
Dequ: Buselzus go bip gne ewrt-ttaekojq ZTLG siosab ja 5, it uwsdeizum ar Gpofbis 6.
Adding background modes capability
Next, back in Xcode, you’ll need to add a new capability just as you did at project creation.
When a silent notification comes in, you’ll want to make sure that it contains the data you’re expecting, updates your Core Data model, and then tells iOS you’re done processing.
Pio’js riot pa ehdwoxofx e sec AnwCuzidepu pagsub jv eytuyl qubfitadm pesu em IwdNuwokida.xcuyl:
Vyofb fkcoix ul qiib voxabelizeew fiftofp ez? Niq luju? Ctom an nobi iwc doga sadi wye Runi Caje owaxefoikw bij ar svo mqefas ncfiiy it piaw Fama Yuqi luwdemsuxx lozfaocuk.
Shuoqe i nef Deksuvu udyunw okg madcluen wqo uhazo.
Panj xiesmawg a joh xuxu gubigm xayf hucanodiluayt ogips qinjubuql upiguy izx veld, uld sue fweoch kie naep kucmi urxaxuzw afrzaccaivilg.
Method routing
The following table shows you which methods are called, and in what order, depending on whether your app is in the foreground or background, and whether or not the content-available flag (i.e., silent notification) is present with a value of 1.
Key points
For iOS to display your notification while your app is running in the foreground, you’ll need to implement a UNUserNotificationCenterDelegate method, which is called when a notification is delivered to your app while it’s in the foreground.
Good notifications don’t require interaction, and your user gets what they need at a glance. Some notifications are tapped, however, which triggers an app launch. You will need to add an additional method in your AppDelegate.swift file.
Sometimes, you want a tapped notification to open a specific view controller within your app. You will need to add an additional method to handle this routing.
Silent notifications give no visual or audible cue. To enable silent notifications, you’ll need to update the payload, add the Background Modes capability, and implement a new UIApplicationDelegate method.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.