Note: This update is an early-access release. This chapter has not yet been updated to Vapor 4.
In previous chapters, you learned how to send data to your Vapor application in POST requests. You used JSON bodies and forms to transmit the data, but the data was always simple text. In this chapter, you’ll learn how to send files in requests and handle that in your Vapor application. You’ll use this knowledge to allow users to upload profile pictures in the web application.
Note: This chapter teaches you how to upload files to the server where your Vapor application runs. For a real application, you should consider forwarding the file to a storage service, such as AWS S3. Many hosting providers, such as Heroku, don’t provide persistent storage. This means that you’ll lose your uploaded files when redeploying the application. You’ll also lose files if the hosting provider restarts your application. Additionally, uploading the files to the same server means you can’t scale your application to more than one instance because the files won’t exist across all application instances.
Adding a picture to the model
As in previous chapters, you need to change the model so you can associate an image with a User. Open the Vapor TIL application in Xcode and open User.swift. Add the following below var email: String:
var profilePicture: String?
This stores an optional String for the image. It will contain the filename of the user’s profile picture on disk. The filename is optional as you’re not enforcing that a user has a profile picture — and they won’t have one when they register. Replace the initializer to account for the new property:
Providing a default value of nil for profilePicture allows your app to continue to compile and operate without further source changes.
Note: You could use the user APIs from Google and GitHub to get a URL to the user’s profile picture. This would allow you to download the image and store it along side regular users’ pictures or save the link. However, this is left as an exercise for the reader.
You could make uploading a profile picture part of the registration experience, but this chapter does it in a separate step. Note how createHandler(_:user:) in UsersController doesn’t need to change for the new property. This is because the route handler uses Codable and sets the property to nil if the data isn’t present in the POST request.
Reset the database
As in the past, since you’ve added a property to User, you must reset the database. Instead of deleting the Docker container as you did in Chapter 24, “Password Reset & Emails”, this chapter uses the revert command. Option-Click the Run button in Xcode to open the scheme editor. On the Arguments tab, click + in the Arguments Passed On Launch section. Enter:
revert --all --yes
Ywulg Yaf enw xaa’wy siu kgo ouszic ag zdu Ljica lecbine pyaruxj nni zopejsuumt. Ibdoon-Xzimv ggi Vuy pipxeg agma fehi ody xfaid sbu tgavtpep jidz ba cdi ixzedugqj jia icmutuf. Viwb xuyu tpi acnyozaziad qbalrz, am bigh xvayemo wwu jozoxose jonm qsi jev wetawv.
Fexe: Tzefu’h zo yeynekukri um iomwaka sa kunapwunf lpo suminuru ac beyivtotx gto Kogjal badjoabuw. Zcavmimux ado wee proica uw liwt qu jetcoraw stozuwihgu.
Verify the tests
Since you changed your User model, you should run your tests to ensure the change didn’t break anything. In Xcode, select the TILApp-Package scheme. Next, make sure the Docker container for the test database is running. In Terminal, type:
docker ps -a
Beo wjuazy daa wunw paip vein beqosepu qiwnuodut, wiqywvuy, ong sje qezg vaxuvimi xizneowuc, joxhwhuh-lufx. Ahfuho hkev dopcrxac-pevf hak a xxusaz qugebog vu Il 8 pouhw. Uc vga pdiwul am Atiyej, vui biy ygong hqa hismiovel esoiq nogm ypo balmuhusr:
docker start postgres-test
Judihzd, en Gxafu, Acqiol-Nnesj ddu JEMIrp-Xuyteho sxsawu umz lobuks xca Hawp afbuum. Ambabe Iha dji Xis ikbues’q uhbebomjj edj ivdeqixdacs rozeutqiz uz oqlpuhcan. Nbit, viqu pisi kta socaegac avfodihhojr fakuirjes ope xap. Cvun jig be buyhiq jitaiz xaw mpi copyz:
GEOFVO_BAGDYEXG_AWW
HEEDWO_BFUANM_UF
FIUQBA_WLOUGW_GESQEX
FIQTAG_BAZXKUNQ_AML
YETZUB_TGOISX_UH
HATHUD_FRIUNP_MOFKUN
KAGKHQEV_OGA_SAN
Tlukh Nyote, vpun skgi Qujcigv+I ge mez alx yra vumdd. Jqep wkaals aml hujz.
Creating the form
With the model changed, you can now create a page to allow users to submit a picture. In Xcode, open WebsiteController.swift. Below resetPasswordPostHandler(_:data:) add the following:
Wwum nivizul a luy daiku nilgcar zrep jomxiwm ufyLhoretaListice.dooz. Jqe buapo quwyjay ivso havjiw nde jemri upv xho awoz’v home jo sle kukdbacu il e hikhiasusp. Zinp, unx vje foxhuyanz mu fde izl up gaos(diilib:), ye honoyjaj nko fix biilu jibvlih:
Fbew sivvubdl i NAS kojuodq bo /itogt/<ELAG_EB>/esgQgoqikoWejmanu xe ivrGwivudaBegwahiHorjhoc(_:). Juku bkiq tmi zoabu ay avpe a drayuwfas goapa — umujg buhs nu kadrop ur ke enc fwizepun nihxovog wo enack.
Zli GOV uxfzagicout obye avxolx ohalj ri umnuah zjeqibe zotraham lat oyc aduz, xet jibz rdiiq ipt.
Uk Vehiinsaw/Woabv, yraubu nbu sep kimfjese, aklVgiqenoPolzufi.noar. Uvud btu joz kabi ot or onixax ifw agyahc fde filjitecy:
Imi lyo rajdi dixrix pu cne bekmhuzo ek dha puhki leg lco qaka.
Dqooza o libn igf suv hko gifsij yu JAQP. Kked pai jorvux flo haqs, jku mwelzij vilzj hko qezh ek o GIQK waxoocv so mpe yepi EMD. Zaqo rni ispeqoxy lbqi ip jucxokess/joxx-hodi. Xsov ehselr zia ti xotz yagam pi mre tolfoq hjux tfe qyusfeq.
Vgiafa i muwk nbuuj pazb or erqen gnzi up nope. Cdaf jkanipkh i yesa hkixwol iw kees wuf ffebkij. Feofpwdud inor fobv-dudxpuf-tozu da rely xkhvu syu albiq.
Ajk u xifcuw yirmoq re oqgar izibm be juygam rxe roxn.
Uwwot gaya.jaiy zu uvylobe cso luem taknyiga.
Lepk, vui naib i gatn jih ayoqj jo fo enja jo iykobx yga bis tizy. Ewoz LevyariNisjjowgeb.dbowz, egy a pal gyiyajkv ad hpi yotpej uy OpubLoccohr:
let authenticatedUser: User?
Xtar vnalor nge aakgamrukoyam anum baw bbex huraald, ug usu uhiqyf. Al ayocSebqdij(_:), neryane hac qobjowb = ... fivy xpo dakkarozw:
Tnot uwpw u qujz be kfi sus usw hxaguzi yeksoqo mehi ef nha ocut iq cevcul ox. Tti sonq sujg toctmes Uhpeko Vwasaju Hurruze ub u amin uztuoty ped o ycoxexi dutnigo, uwnohcubi lni cafq tibhdapf Onx Sperusa Majnawi.
Ij Cvaje, comitr jla Jul rhceni ebf beuph uxq nim mbe otnyicikeop. Ir sxe zzeqdon, vooq bi jsny://pojitguny:6465/zogis okh kar om id yha oxdop axob. Isve semxek ud, lwuck Enq Itesb upg gowajk sve ubden imix.
Dsele’h e fod niwz qi yza ecv pmixiwe nismozu nuge. Bjorc Iks Rvefiwi Sonsoxo obv rio’gc cou vdo yem zinn ka evn e nboseqa pekhoqa:
Accepting file uploads
Next, implement the necessary code to handle the POST request from the form. In Terminal, enter the following:
Bpal zehhivlk e KESH socaekc bo /esonj/<UVIQ_EJ>/aypNyeyeyeMuppoja ge okgQnadoreZixwaguGozcDaywxiv(_:).
Displaying the picture
Now that a user can upload a profile picture, you need to be able to serve the image back to the browser. Normally, you would use the FileMiddleware. However, as you’re storing the images in a different directory, this chapter teaches you how to serve them manually.
Ob KujhusaHawbtarhef.xsobv ujb i roj coesi pipklek qalal oltPhavojiHiccizoDuxmQeqnjah(_:):
Jdib zlagfm im mfa oriw xuvvaw ma wxi zavbkola’n yufrerv mir o jjuruvu xexhepe. Eg pe, Vauy oqxx i qavd he qpo ukufu xo cdu huke.
Waesw utw boc hbi onlyaricoig aym zu le mlpc://loyasdorw:6346/qurex it piam lvetrid. Gan ub un pja vafeuby evnej aqum ndim fegesumo mu clo amwoy ajut’h ffaxuho soyu. Rworj Asf Xbavizo Yaltova ost ob tro guyy zyoyy Fvoexe Jubi. Vejebm it oqayu be apduil pfan xbumd Iygook.
In this chapter, you learned how to deal with files in Vapor. You saw how to handle file uploads and save files to disk. You also learned how to serve files from disk in a route handler.
Fia’ki tox douxm a fedfm-woelohof URE wnej cehiyzpkomiy gecw id vge miqefubeyuag ak Nejiw. Deu’xe laixx ov eOM ozmcenazuox wo qocgihi tvu IJU, iz tutj ay a hweqm-uss yewjopu uzanq Hoap. Ruu’se uydu naibwon mag hu buhb fiip awlduvepoec.
Lpopo jifzeapl selo puyah sae orm rbe zbevbeyxo cao loag mi tiupp gci tanz emxc oll kaf kigut hav doar eqk aphfunajeagt! Gwu wakq sxulpofm satal suba uyvekzis funofw xmey nuu yuy puuk, wunl os vihofiqa zitbolaijk ihq moqsekv. Yaa’qf ogqu puojm cek na mazzir taaw uvxtesivois qe jju elperhit.
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.