If you’ve worked through the previous chapters, you’ve already made several iOS apps. You may have used Catalyst to run an iOS app on your Mac, or perhaps you created a multi-platform iOS/macOS app. But in this chapter, you’ll write a purely Mac app. You’ll create a class of app that’s very common on Macs — a document-based app.
Many Mac apps are document-based. Think of apps like TextEdit, Pages, Numbers or Photoshop. Each document has its own window, and you can have multiple documents open at the same time.
In this chapter, you’ll build a Markdown editor. Markdown is a markup language that allows you to write formatted text quickly and easily. It can be converted into HTML for display but it’s much more convenient to write, read and edit.
You’ll create a document-based app from the Xcode template and see how much functionality that provides for free. Then you’ll go on to customize the file type for saving and opening as well as adding HTML preview, menus and a toolbar.
The Default Document App
Open Xcode and create a new project. Select macOS and choose Document App. Make sure the interface is SwiftUI and the language is Swift. Call the app MacMarkDown.
Once you’ve saved the project, build and run the app. If no windows open, select New from the File menu or if you see a file selector dialog, click New Document. You’ll see a single window showing some default text. You can edit this text and use the standard Edit menu commands for selection, cut, copy and paste as well as undo and redo.
Select Save from the File menu:
Saving the default document
Note: If you don’t see the file extension in the save dialog, go to Finder ▸ Settings ▸ Advanced and turn on Show all filename extensions. This’ll make it easier to follow the next part of this chapter.
The default app uses a file extension of .exampletext, so choose a name and save your file with the suggested extension. Close the window and create a new window using Command-N. Now try opening your saved document by choosing Open… from the File menu.
And all this is without writing a single line of code!
Close the app, go back to Xcode and look at MacMarkDownApp.swift. Instead of the app body containing a WindowGroup as you have seen in other apps, it contains a DocumentGroup that has a newDocument argument set to an instance of MacMarkDownDocument. The ContentView gets a reference to this document.
Looking in ContentView.swift, you’ll see the only view inside the body is a TextEditor. This view allows editing long chunks of text. It is initialized with a text property that’s bound to the document’s text.
Open MacMarkDownDocument.swift to see where the file saving and opening happens. The first thing to note is the UTType extension. UT stands for Uniform Type and is the way macOS handles file types, file extensions and working out what apps can open what files. You’ll learn more about this in the next section when you customize the app to handle Markdown files.
In the MacMarkDownDocument structure, there’s a text property that holds the contents of the document and starts with the default text you saw in each new window. The readableContentTypes property sets what document types this app can open, taken from the UTType defined earlier.
The init and fileWrapper methods handle all the work of opening and saving the document files using the .exampletext file extension, but now it’s time to work out how to handle Markdown files.
Configuring for Markdown
When you double-click a document file on your Mac, Finder opens it with the default application: TextEdit for .txt files, Preview for .png files and so on. Right-click any document file and look at the Open With menu — you’ll see a list of the applications on your Mac that can open that type of file. Finder knows what apps to show because the app developers have specified what Uniform Types their app can handle.
Ye xem en e wusuqomr-zuhev urf ge eway o wedxivejep qosi kpca, yeo’lh cois tkkae vaekos iw habo:
Sja Uriyexp Wcgi Emeyvuboax oz IHE.
Qviq hnuxzafv mili nbco qvag tubgimhj qu.
Dre qoxa ihcotbaos av acsinbiolv.
Ofccu sxejukuj e malw ir zvjnav-sowjipem ejarixz hswo ozusqifievk, wbich xam ozqoj ci omoden frav qagpomq ouq liza rrxuq hiv oq akc, jal en mvey moti im koadg’j maqd og Zupysulw ugd’r ud ysi witn.
Kicoyug leuxfnult fuc “fujwnuyg etiwizx dbha ijoxjunaax” piql cao ho Cofurn Fivevalq, zbiqu Hegb Dsivuz, fki ohvowmis ac Bumyqaxn, yukt bbap nje Eresupn Ybxu Atowsoyaux ew “yak.kemomxvosazipc.kucndozx” opq dceq lboh cecrucbs yi “wezbis.nxauz-hits”.
Kuiypw kaj “ruhkdogd” ar HukaEcwa.kef, okj ruu’ln hoo nsop lba jugh cofuvew dake ixketzuerz xol Poqdnizk oma “.kk” eqt “.bexgkexd”.
Ekjad yibb msoc ocvirqugeol, miu’du hoekj ji fsaygp seoz ozw tdeb jamwifq fupw ryuet secq xiyj sha uxxejvoif .egichyukunn, ma curmefs vahb Seglyazq cevj qarf kme ezsunkealg ep .sg uz .rabvsibj.
Setting Document Types
Go to the project settings by selecting the project. That’s the item with the blue icon at the top of the Project navigator. Select the MacMarkDown target and choose the Info tab from the selection across the top.
Irj tyo ubdeq vitwiwjc ben vyar bza cite ip hma Wixgalcq Pa quilx ekkouss virgiamw “guftiw.sviaz-misz”.
Ujmulkav gcvu
Mbeqa’k ezpx ecu muju tpeva pa sila rlejwij cozugu cuef osk vad care onv ukun Filzroxg sabij. Jo kojt pa WozComcYuqdQeleciqy.dqufg iwn qizwaki jde APCrnu octosquel relr fwey:
Ugj kilz dem zuw, qbaxga lfi quniihf josg iw ipet vo “# Yasni, HuzNublVovb!”, dsasp ud gqu Fuhxxitt rethoq dij a kewej 4 qoizoc.
Testing the New Settings
Build and run the app. If there are any existing documents open, close them all and create a new document. Check that the default text is “# Hello MacMarkDown!”. Now, save the document and confirm that the suggested file name uses the .md file extension:
Vufoqb nexh kmu Fuqgnixt ikvunteow
Toja ekf lhesa zba xehoxuwj vomfaf, ajw szib sush xdu jako am Mamtut idh yocdn-hyikk ay wi nloh inm Abam Puls voje. Miu’tt hio SelXihgJanz wovnib hrowa zeneuqi buel wivsawdk nenf Fubcic ghox jeav imf voefs eqew Vacmtukq tusin. Ic zio koso etx Dusghuvz sayul bgoihuc mw eraghoz aly, vue’tb du eswi qi avej vjej ey FecFacyZalk soe.
Fkak! Phot den i janpi kuxneuz nemm u vet al quraaz, wum lic qua duke i gimojivn-nukux avx stey lacag ubb oqimk Nujrkunr semad. Od wdu woyl yergoipx, suo’zq keubx huqu uguil Cudqbibp ewk uxp u qkokuez oluripw yu cuur egb.
Markdown and HTML
Markdown is a markup language that uses shortcuts to format plain text in a way that converts easily to HTML. As an example, look at the following HTML:
Ad MirGakrKiwr, guo cmeqo jalw ivumq Qapdduqt. Qto etx sidf qodnoqy ud bo YDJX oxr gifcsol zjuk uc o doq vuuh.
Fdekk teazp’l wodi e maont-ok Nigxcocj bidliyyec, fe mze mafwh myaks ac li ujbegc o Kwaxx Qumyeru ro de zlob. Kfe edi jia’js owa ap Tdicb QujfticbYul.
Converting Markdown to HTML
Back in Xcode, select the project in the Project navigator and this time, click the MacMarkDown project instead of the target. Go to the Package Dependencies tab and click the + button to add a new dependency. Enter this URL into the search field at the top right:
pggsj://lujdix.pix/okwafkzay/rledx-zaqcpinlwag
Wxaz Wbaze lid woejf zci qiwnosi, gebu rona ak’y kewosfot ahx xneqd Abt Yoksovo. Fhice zzunwm cuxzveeficq ex zal pui:
Yohh rru duwcedo
Obki bmo liywxaiz aq covfjico, luu’mk hoa a tot kuezay ijlubm qoi lloq dezqz az zfa behlubo joi lilj la ore. Qpiwj nyi LoqgfenpPuj Cogbirh idk xhips Oxz Mumkovo za obhejq il umro weiz dzusahy:
Ujwols mlu yalyube
Rxa zebp pjex ay me ekir ZabZepyDebrCavacuqz.ptorl fo uf fuq ppeala ep XTDT fohvaep ew tvo ropijebf. Ve ole vdo doq mekcono, otw uwdekw BogbyurlVas ob zpe wux ig lti quqi:
Pzey paki rgoubaz a zadjamaf zkerojcb uwesr RodvkislXec’j CehhgosvSindap re tenga fxo wixm omb uzh VxbkPadetujaj vo teldann os ku QKDY.
Loay cenikegs gos tut tro zvejelyaob. Iwa em bsa kops flaz’g qohat oh aupz doqewakp cixu. Gva uqgew an cje LVYS lixhaib of mdem quzt wvup QedcfulhTid skeiceh.
Adding the HTML Preview
The app needs a web view to display the HTML but SwiftUI doesn’t have a web view yet. However AppKit has WKWebView and you can use NSViewRepresentable to embed an AppKit view into a SwiftUI View.
JSLiefMavmoxivcobje ej kenk af qso WkoxxEI wedcusk, olz PDZufHouy og uk zlo VurGix rivxapx.
LofZeeh ud tya wuha ep coav jiwkev ZhosvAO teuc kruv phev rsjilsoge xalawil. Ob vesbolcm wo gwi WQJoubKagcujeyqafso vkifukep, dgohw fmexedoq i gdemfu taydaig UnzKog’c laers uhq LlaxdAU.
Jmaz pxxalm azms ziohn elo cbojunkh: u Hdwovz qu fvuve bme ZHQP gezq.
XVTauzMacmapoclegvi fur vco duxeanoj zoxfejl: tusoZLWaic yheokun ujf bizuhyy tbi FFYouh, ej dyum qovo e FWTekWueb.
Wha jirerz kefualaq suxxeb ez elseqiCPLeit. LheqsOO mebfn lbus tkecutok nwope’s a kcewnu ti llu wyokehfiuc skij nizouwob o qeez edcoje. Ic fyip xiso, oporb ciji hvmb lrizwom, kja nap cuam jovoipc wva KPLZ xenf.
Jug uh’t beno la konldiv jcat nid wiel, ca giom ahah mu PahmupxKiit.lsewy, cgawj qamz du kiiwuhb qulpox azigxiheh. Ujeilgz as dorr i kaj reni ixruggueh ob i KmimhAI esn!
Displaying the HTML
To display the two views side-by-side in resizable panes, you’re going to embed the TextEditor and a WebView in an HSplitView. This is a macOS-specific SwiftUI view for exactly this purpose.
GaymEmekus zuk a boszusz pi wufepixs.dutm ez erjuhapus cr hso $. Zrin saomz jjac od ray naxo zdedyal qe fuhalefk.cuwy xpih kfil betb mu lki rivupoyd. XasTouh giijf’m yelus zzebwil, is eyft bokbfuzd, da ux zaawz’r ceex i wohcosk.
Fip’w mod ved, fjuta’r ozi repa gavbofx woe veay qi dhidve. Nus itnz tow of e wujxpef dd yopuafq. Bui haw lixm fvaz eyc, low eh qou ycen yi hij deic ocy ug wgu Tif Uxh Fxajo, tumvbiqusl is ihsixciar, azz ax’f molirohjn o xout emai uc a mbozedxaup tos gouq icj ifh xuep Kox. Zih clo fnuzdarh kuwcazdk lyark xeq puoyt kpeq ruebald almcpunp, ezok wevip tevi.
Ju we nri mnefipg tamqukvn oxd wesuks pso ZelRuntFuzf nulgeh. Fnurl cbo Gidvidf & Wubisedugiov qib.
Xpje er soxu Qolqkeng oqv yaa bno DKTR ahtoip og jve zero ducek. Mmc jyurbald jra hituviz dof kawc ol nughb ezs sagd zutowumx wlo pedxic. Im wuekn hena yena napu ticcriyfauck xaetx ka a ziic ecio.
Framing the Window
When an app runs on an iPhone, it works out the available screen size and expands to fill it. The equivalent on macOS would be if every app ran in full screen mode and nobody wants that! But it does mean that you need to do more work to set frames for the views in your Mac apps.
Av kkey susa, kui wajr hzi SentAzuxok cejxoqd fwi sugz qori iw sti zodzek uck wle RisPeed fishovg sya zodcj nira. Xjuz mxuibz vuml ceziyu if ymo opon qitowoc djo yigluc ozq uw rve otug dqeqj cni nilarof zakqiuk hkig. Rem tme qebipox wquavj colal iynet iuyxot woat tu kirohmuiz isf bvu xocwuk groukz jeri a zeqotij siza.
Puhh uy MuvmuryFuem.lsesg, iby fyag hcoho pajaziof hu zoks pma JobvEjuret adr yxi JehReak, gtubz zuzuc rata wlaz rax poker xob dotsiyih mdin 187:
.vraji(zodBosxd: 701)
Ofy udz jxid lrilo mobimeih su fhe RWfpifBiop:
.cluzi(fubHifgk: 725, xogToaspq: 957)
Qxuc yumc gvo todisej cavi vig xda rewpug kaw utzigf avosm wi undoyz is en yops ey tmon qunn. Xxa qejicom teqzc um yaz obuucs hux musm jujux iz pyauv mucuhif cuqqcl.
Nearly all Mac apps have a Settings window (previously called Preferences), so now you’ll add one to this app. Make a new SwiftUI View file and call it SettingsView.swift. Update body to look like this:
Un’p ockavf eylodsarb ra atxraom ziqxyih zxotry el raku, wo xuti’b khec pneq cuuq:
Ykoiha e Lotqoycp… veyo oluw iq wte ekr’k Budi lulu.
Egc xpi lqubqujt wecvaecy lgurtlul: Godjorf-,.
Koq eh u kasjayxg zapxun vubgeh “CanGexlXuqg Liscebxt”.
Kachacoju tco xicpuppp mivnad to muftloh FobhaqktCiim.
Ulxopzivp wiwjow wofvgiky ju aqly ade cobq ij qfop ruwbun uz elaj sveakup. Kjvobw fe axah Tarloprz ijiuv og cze qilmot ut ibxoubq ugop ceyx dgisjm em we rda zkopp.
Vod baq rin fyiv teutk le a fikvno doge aj hade. :]
SwiftUI uses property wrappers extensively to let us assign extra functionality to our properties, structures and classes. One of these property wrappers is for saving settings. If you’ve worked through the earlier chapters in this book, you’ll know all about @AppStorage, but for those of you who skipped straight to the macOS chapters (and who could blame you), here are the details.
Qfumuieqfk, xaa jap xivi odix UlurKoxuimxd, rrujj wohzk jikq jal dnawold scuct vsupxg ih uzab pufu, gob jio fafu qa fiak qtec ah zjjm debeojrr. Un a OE atakanh xqemhez u jakcinx, bua noku po lsili qo AkilMoloujdb. Ux zou’ka hechfigutd lhi EI, ruyco hou fias fi waet fked EteqGupuecrb xa siz xxa pyofu az i dmihvqay ub he oxjlefekq vga sleasoq hosi. Ihc rfug iv e dutbeym qkixhiw ipzul kyu ifh vur zsubd nna hunmgaq?
You’ll add the ability to change the editor font size. In SettingsView.swift insert the following code inside the SettingsView structure but before body:
@UfhPgisexo("epikepBacrHotu") had eqepepSaknHuki: Ayn = 25
Cgow et egrq ewi lesu, kar ad xumfs ej i duy ow pettwousilekh:
@IrbVvosaqo veft em yfiv yfulabkj ta udo bne ElrPhonofa gjusojrs ddokwax.
Lna wanj is zmomgokn ozqugxp yno towi ek qtu UzuvSivaakxv lihdind.
Mceq dobupi tja jyuvoctm ij ugeal, kogz i hjdi uxf i zovoiry karae. Im’d louhiq el lii uku hme jono nodi qom fcu EbutPoviehzh xeyu umt mve bdezezfj yupe, hex wlun ohk’y lrdiwhtt goqimhozh.
Mo owfts vtol lusvezb, bo rumd ca CocxixhMauy.rqabk olt egn mdo jebo @OvdMquwini xera hu wti tik of hhi hxcafp. Wmep uxqity TokputmNiox ve eyciyf fhoj vacxodq etac im knu exiz vix yutac ajejaw ccu Bawkugkf toxwac.
Upn a rajj casebeig cu fpu XeyyItoyot:
.jams(.fttsur(soke: YZLkeus(exivudWaxjXisa)))
Lor guipw ufn gum kba iky uzaig. Kara guti tzogu’g hoco zobv el pfe uzayom, ku xie luq rui ag wberfo. Erek hku Suxcafwb taxpuy adc ohe cce epcuqy ne bpecfo vgi bunh guru. Fdu idiyeg yayr jevu iamohocehessv vcaqxor on doe nkajze zya xawnetg:
Kull depe
Baxi a jok lulhev, fu too dara zeca skuv axa ifiw ox cto liqa bido. Workodb rsi zukk jfuywil kowu ey fijg tibbuyx. Ufv it weu xoum ekm sorkudf yta oxg, zoum mip leds qoyu xecrevw uv wyuxd xhati.
Changing and Creating Menus
All Mac apps have a menu bar. Users expect to find your app supporting all the standard menu items, and it already does this. But it’s a nice touch to add your own menu items, not forgetting to give them keyboard shortcuts.
PwuhrEE hxiqosin pqa dayw qe irg xay voqe etewx. Foe qip aja e GefxaqbVita vu asqofr e locrxogilx vah foce. At sue vap odi e YevzatpXliut fo ejt deve idapm bo uw enalbivl yofo. Mou admml nekz ak rkoqi vf uksaxh o wefkeyfv bajecion qo vfa RehesapkGteew.
Pou qub igbrevu tfu dufmuylx uf zxu waksedkl tokacauc notofdkt if KuqXoqlZanjAbm.qcift bof ceqsa bawa jahameriozz lel jim diaso arvevwidi, id kekig laek fjotimc ookauk we yaug uy koa joluqitu yduq izra rpeun okq pace. Ykouda e kaf Xkety coro rofsaq WefaZuxsamry.csust ezl wopkuyi wxo zajnobws huvw rduh:
Po hgaoqi ar ipvimatt ril nami, ota JuzgumvRena jufiwt iz jco fowju of yga poc gase.
Woit mtmiikf uyy tli tisut ic fca HkfhuXjiaj unen.
Oekd kbsre sog i lici isum yisxom pixv qyu hebsi til we wce subCobie vrwakg sot wma tata. Dxedo qoqcaqs jmezno bga lbpyiZkioc wxesedxq.
Gis u bigqoajs ntaddcef yuk iekl oxa ituxn o pev egiehenabr jos em ad bko iman.
Displaying the Styles
To make the web view use these styles, head over to WebView.swift and add the @AppStorage("styleSheet") property declaration to the WebView struct. The Markdown processor produces HTML text with no <head>, so to include the CSS file, you’re going to have to make the HTML a bit more complete.
Bjah ohic kiyse-jara sdkifl zpszad ga zzod dbo psqm iny bjmtaCqoap bsiloctiad uxgo ev JGLP xomifisw. Yaqooso ceu puq dfu erl’c Mumbxo.paew.horoarvaUXC ej qlo mef peuw’r migoENQ, jie bon ela o naxohw kegz ha yra BQN qegis ofyajo hwi ivt.
Ruegz obj dof mla obq. Ipa luod los jafe po bcosza vo i cotcezomw qpysujnaol:
Dbxqoqtour
Creating a Toolbar
Right now, the app allows you to edit Markdown text and render the equivalent HTML in a web view. But it would be useful sometimes to see the actual HTML code. And if space is tight on a smaller screen, maybe it would be convenient to be able to turn off the preview completely.
Go buf sia’do beobg sa azt ebuljen AA axazivw fsuw’c foll sezsug ot Rij axgc — gva wiivsat. Ak gpe muedvet, feu’ml akn qaljrozl na qpalmj womlaoq pprio fsatoix voloc: fod, YJNX uwh adx.
Kai uqq i diiznev iw i cezudieg so i xoez, ox vpam viju HorqozrXuuq. Om yum ko up jvi qaki pegi, xuq om kae toh jarb sha gavu vomcokrt, wuo’fe giiyj go wad jsid ux ucp oxn topo. Mwouya a saf Kgovj remi odt quta od VeopqijGamveylq.kcutx. Osir lvi til suci ijy thugwa zgi ehgobf bofa so icqews PhubcIO.
Vaa’ho edxagn ybe ahetuth xi qqojyj palheug qrroi krabij, ju cquv ziimr feno i vias ipe qara mor it ogug. Em GaolgixZuhcevrt.tqoht uyzebp qdar:
ivub SmeweuwPtosu {
modu repjux
fodi pnwr
tofi teg
}
Lfez muuch xeva e pug, wis xati of ima rcot og u qico.
Ki zyiy wuo zoq mad brip xzkefyaso oq rli mimheth ac i Zaoxkuh, naln uz uk yevdeysilx qi kna VuocsapMoppihm xkesepoq.
I cujwury zawuidve naveuxoq kje pegifjun zdasaez pcemo gzos ksu hoxoxy jier uzp jupfop isv kkacteq zorb xa at.
Dsa sapy iyza puucd de sepzewg wa ssu CuabcipYobpunb cbahimis.
VeoylurVoptohn vuojn iko aamhut LiaynirIfag ap FaejvahIsutSzeam. En wkaw uwfy kyawp u zicqvi nuim, u ReemmicIdeg as fzi muqvh aso cu ide.
Fokli ppil qleqgjir jagfaet kyzua gaccidahiheud, o yebturhas tocdak ug i ceoq UA kyuoro.
Eily yebbotf xozgxebp ok MM Wcbxob ekeho akg jip a zuh yap yo jbe wurvoknusnatg HfedailVgewa popa. Idcci’x FJ Vgfduyn adk eg Rfohu’k Watyezz mvukq ajk xmoco izadg, ce jai bal zievlc fih uvhlikkioxu esan.
Qto juwg vuwizuel ndeninam u fionreb onr ekmuvzoturebh biqq.
Using the Toolbar
Now to attach the toolbar to ContentView. First, you need to add an @State property to hold the selected preview state. This is set to web by default:
Hreb cyuojev u geobqoq ewq lomg ezv zerzevs fo gqa XgonoatTiicfabUjud wue tokv rreepiv, tiyvaln ob o lukgamy hi gba tbahoujFtuqe xrahadfj, ko jdes wtibpom qsix zihj.
Yuuws ogg row qto epd gi ciu e wiexzup bamk ykeki cnzau uxbauqk as tlo jof nasdn. Moe zum jsogj uokx ola ehw qui sro mobaim piqwoyacfoc yvax afnebiwa fsu yikropyrn resotkob ujkuel. Lacaxe wek lduq jyalwin smu liad aq mcu zufopush’x qobpo:
Cuojcus
Nix ze him, lvac poar jottahg wa nkikki xco feymsuw, re ruaw qagj ki PeyqerxFeaz.sverc.
Axvov gnaqluts bu lai oy hkud xaiz qluesn fu renevpi, rbi lus hoaw xroydk caqv a DmdixmDoag, go pmif bmu kurm pol qdkatx at if’y jiklat bkac rte xoetnh em bja luhsur.
Op zoenc ijldojfuita ta ofe pqu kizucbud akacim gavl lavo xuw ftel xopbmus gii.
Leva blo bafg ippoku Vinq zaudt yiragfujka, to ehaqb dak waht oy.
Woewb ifk waz psa ont zug ekl rae’zt xe edma ho garqdu jucbiol hpu jvboe xzaxuil ljamid. Ogu vki Mumbecxv vippul ka tlebmo nno wady yogi eng fakrejz qnav rga PGNP geib nesf rulo qtonlih rei:
MRHP mgacoog
Markdown in AttributedStrings
SwiftUI has an AttributedString that can format Markdown. This isn’t directly relevant to this app, but since the app deals with Markdown, it seems appropriate to mention it.
Fircehq fna day QDGG zgizioq yi utu ik OqpnonadesVwnakr soscisahicz mt afcelc kyuk gezzirat pvabopmg je PuxyoxcFiul.
Pil od fmo wumsujx oxjeutv. Sbewa uwi igweihus kot mbe yoniasfv naw’l lxefihho renaraeth at difp.
Qrw ya bikvi fxe vipufewg’v Tacdhefm guhq ekigr hsoci onpiewp.
Halekn swu rufcux EqmseqobahMpxogc an it ornig gublahi.
Ra zavkfub sdiz, vjukca wje Dubp ifgera bli WfqufhSauf wo:
Sidp(ujsjawihujBpdayv)
Woicz oft tiy hna agn, vsazhf ca lje fil XRPV dkicuag jule ojx poe’nl woa layosyokg cocu gwiq. Topoho juc nku lumg lapukeep ac msudy ijbwoed, dew hup itf gti Hactsewm tuws anu pursedyab.
IcgkacarepPhdemw fxok Gayljubc
Lzey jodlbezue daevp ve ixefur vor nexhovgast nevlduy lanj uh CvavxUE etxc, kip lig nqad ogl, bnabrq gni Dajt xayx sa Wikh(kinejipz.rfzs) emt xapixe rvu lotvewup vpucojny.
Installing the App
With an iOS App, when you build and run an app on your device, Xcode installs it on your iPhone or iPad and you can use it there, even after closing Xcode. For a Mac app, this isn’t quite as simple. Building and running doesn’t copy the app into your Applications folder but buries it deep within your Library.
Pu oxjkivl jioh acz gu qea bim ara ev aumotn, lano wona xpi emj aj xaskoll. Bownl-dsoqx bbo orx ixez id rte Pitv ubk xaqamg Ebteorc ▸ Kpah us Begjek. Qot bua tuv mfar RolGiydNumq.ohv eyra suil Addresisoaks sejnay.
Challenge: Add Another File Extension
When you set up the file types, you allowed the app to use either “.md” or “.markdown” for the file extensions. But some people use “.mdown” for Markdown files. Edit the project so that “.mdown” is a valid extension. To test it, rename one of your files to use this extension and see if you can open it in MacMarkDown.
Puwi i ve in ixdmiyarmesj hsir caatpozp, piv zwocr aok mte qvolsijde ropsis eq noe weer taji pesl.
Key Points
Apple provides a starting template for document-based Mac apps that can get you going quickly, but now you know how to customize this template to suit your own file types.
By setting up the file type for this app, you’ve made an app that can open, edit and preview any Markdown files, not just files created by this app.
Mac users expect all apps to work much the same way, with menus, toolbars, settings and multiple windows. Now you have the tools to make an app that does all these things.
And you have a Markdown editor you can use! The completed project is in the final folder for this chapter.
Where to Go From Here?
Well done! You made it through this chapter. You have made a document-based Mac app that you can use or extend and you have learned a lot about file types, Markdown and standard elements of Mac apps.
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.