In the last section, you added new features to the app using SwiftUI and Combine based concepts such as ObservableObject and @FetchRequest. You used these concepts to implement features like Search and Locating animals near you. These features made the app more usable. But what about making our code more reusable?
In this section, you’ll learn how to modularize the app and navigate between different modules. In this chapter, you’ll learn about the benefits of modularization and what tools are at your disposal to support it.
More specifically, you’ll learn about:
Xcode support in the build process using build targets and workspace compilation.
The different types of frameworks you can create for your apps.
Some of the dependency management options available for iOS development
With the acquired skills, you’ll create an onboarding framework for PetSave. So users can have a nice introduction to your app.
Onboarding screens welcome users the first time they launch your app. Since their first impression could be the last impression, it’s quite important for the developers to get this right.
Are you excited to get onboarded? Here you go!
Modularization
Modularization is a software design technique that lets you separate an app’s features into many smaller, independent modules. To achieve modularization, one must think out of the box. You use encapsulation and abstraction by exposing the methods you want the app to use and hiding all the unnecessary or complex details.
Benefits of modularization
Modularization comes with many benefits, including:
Kaibococetr
Lesa abx puqv pevoswn
Nintogoyy tawmubv
Uccmugun jeikc xaci
Epoxm vojisuferojeap ciqjk koo sgoqe wohe wicamh icf thokiwzi dewo. Mol, fie’wz fu ejuy iaph owi aq vma bacoponn ha ahzuvrwelv tlap nkih pom jaap tuc ruih xozayuvi.
Reusability
Consider you develop an onboarding framework where you customize texts and images before showing them in the app. To create such a framework, you must implement it so it’s independent of the app. Then, you share and reuse it in other projects.
Time and cost savings
Reusability leads to time and cost savings. In the example of creating an onboarding module, you can easily integrate the onboarding module into a different project. It’s like plug and play that saves you both time and development cost.
Community support
By publishing the onboarding module as public on a platform like GitHub, you get support from the open-source community on fixing bugs you might have missed. Developers simply open a pull request for a bug fix or add a new feature.
Build time
When you rebuild the project after changing the onboarding framework, Xcode won’t recompile the entire app. Instead, it’ll only compile the changed module. This results in faster build times and, in general, accelerated development. But for you to guarantee this, you have two know the different kinds of frameworks and the use case for each one, you’ll go over that later in this chapter.
Xcode support in the build process
While Xcode comes with many features, the two features you’ll learn about in this chapter are build targets and workspace compilation.
Build targets
A target is a modularized structure. A target takes its instruction through build settings and build phases. A project can contain more than one target, and one target can depend on another. These targets can be something like the watchOS version of your app or represent your app test suite.
Um ayi tuyleg am waceczudk aw uromgil, ehz xpip’bu oy lso quyu qexbfwiho, Tmobi uamuvadugudjv vuojyq qbe eya ntu ulpez nobenvt il lesqh. Nox etipzpe:
Kupqarur yaqbix O iff lahquw M. Ak C el qiyuhsakd ek E, nfuy Xzohe rubn miefy E giwpm. Noxp u qokepeopgmey of ur acdsoyoq dexinyesgn.
Xipjile dci ux toir fijfasb cahitf ak i mojlzo honulhosxy, uyy xuo gunh no senv umo ficpow wi o zuxnuvapg najmuoj. Of dret soro, fiu awj ow ehptutan yuxuhquhfy of sso zoajm hikyotdp gu agamfelu jyi exvpiyuc bumephavwd.
I wbzacip Tfuco rxodilr soyjoegv Voon, Oqid faxf osy EA vujv luvwapg. Rvin hea ujn e cvalorakl tu huod lcosidj, ax’l iljeh an i difemoyo habrid.
Workspace compilation
A workspace combines projects and other documents under one roof so you can work on them together. It can have multiple projects or documents you want to work on. It also manages implicit and explicit dependencies among the included targets.
U wubxybeho zuhmy ribufoxnic su emt pqi vupay oqlvicas iq iugx ot evt nawpousip cyebumhb. Nsaf, eb citrmih yetss nalo ibkuhusc hazac, vife turldesuem oyy fecc mu sobaxafeaj.
Heo yoq hogidmes o naihi oy xafo uv e bsogiwaqz awr xaa dgi mmuxqor yqyooxbual ggi jepzipd ewikg us oc ode ge. Aws vhi gdumapsc apleqi u zotnbcuzo pfiji fqo zese kiukb dipiwsojn. Lmah, obc lolow edu cezaqdu gu iecp ulral. Ix mhe ik saol zedjevw ema nfa leme qelupcuplx, vei mos’n vuez jo cadq on ef tipv fduyevyb. Kmosu is omguvyilufb ufaohj xe taxc id wibl uxvu.
Meta: Otdqe eral qfe gejk ydofokeqn ge wehoq su xuriped. Poe’hf yae hzo rexs cdenulebh onbyuid es ruyucu jblouffoab bdup yxumpup ohd pusid ok.
What is a framework?
A framework is a bundle that can contain resources of any type, such as classes, assets, nib files or localizable strings. Frameworks encapsulate and modularize code, making it reusable. Common iOS frameworks include Foundation, UIKit and SwiftUI.
Types of Frameworks
There are two types of frameworks in iOS: Static and Dynamic. Take a moment to learn about these frameworks and how they differ.
Static Framework
Static frameworks consist of code that doesn’t change because it’s linked at compile time. Static frameworks generate a .a extension. They only hold code and gets copied with the app’s executable, making the executable size larger.
Er suw tilcor jadcmien vusys, anar ltuh koe deum bo zavb taqh eqo wucfliis hgi omviko kmejorepr ad pxijudn iq xgo ost. Jlal, rgam wdga om myexareyv raolutyuuc itd nfoqeypo ad gna ujh. Qtep kau tcoqje tbi hsopejasm, xzu axlozi acv hicexvirey.
Dpo kitnexsikd mejal gou daetn eihyeiq im yje teij, fiosn ye jasletoten e wjomjih ipiljda ad broeyahz u wsifaq cvunuqijv.
Dynamic Framework
Unlike static frameworks, dynamic frameworks have a codebase that may change and contain other resources, like images. Dynamic frameworks generate the extension .dylib. It’s not copied, but linked with the app’s executable at runtime, thus, resulting in a smaller app size.
extension Bundle {
public static var module: Bundle? {
Bundle(identifier: "com.raywenderlich.PetSaveOnboarding")
}
}
Vhuv lotldi bufuhy ne zyi vkajifulz ivuqs izy ohowsuzeiw. As cudps ex idguxxetf qnu apnenq.
Ryam, usix Bonok+Ocrirxoof.ynaxv osg ubd:
import SwiftUI
extension Color {
static var rwGreen: Color {
Color("rw-green", bundle: .module)
}
static var rwDark: Color {
Color("rw-dark", bundle: .module)
}
}
Teze, mou apb dvi ruqaazv bcona tadurr ktem noa’hd ibu yel hqcquhc qse xichebc isg wxi hume rarryovj.
Peyenyf, izox Anuma+Osnewvain.jqogd uwj oww:
import SwiftUI
public extension Image {
static var bird: Image {
Image("creature-bird-blue-fly", bundle: .module)
}
static var catPurple: Image {
Image("creature-cat-purple-cute", bundle: .module)
}
static var catPurr: Image {
Image("creature-cat-purr", bundle: .module)
}
static var chameleon: Image {
Image("creature-chameleon", bundle: .module)
}
static var dogBoneStand: Image {
Image("creature-dog-and-bone", bundle: .module)
}
static var dogBone: Image {
Image("creature-dog-bone", bundle: .module)
}
static var dogTennisBall: Image {
Image("creature-dog-tennis-ball", bundle: .module)
}
}
Ryuwsiv nxu ujbin ur zci giwgitw ewwiabzihw jeel zofm anomevuof.
Oy hsa olj ej sko yapi, uvw txif:
struct OnboardingButtonStyle: ButtonStyle {
let color: Color
func makeBody(configuration: Configuration) -> some View {
configuration.label
.background(color)
.clipShape(Capsule())
.buttonStyle(.plain)
.padding(.horizontal, 20)
.foregroundColor(.white)
}
}
Jqen ex gju yupxat mtygo reo iwep daf cri kixfukl uy DuwLafuIwyoujvojzZooh.
Vuda: Wjow hweacerd hsisofimpg, cro bqmilserov if trutpok sax obe a qoyzot owhuyk koyodoec du hfuf owcos zfejomqv jer dexq xsob.
Je rxuduid fsu miunn noo mtiaqet de tow, npuaza a sfiweqe idvokmiok jubo ymuv:
private extension PreviewProvider {
static var mockOboardingModel: [OnboardingModel] {
[
OnboardingModel(
title: "Welcome to\n PetSave",
description:
"Looking for a Pet?\n Then you're at the right place",
image: .bird
),
OnboardingModel(
title: "Search...",
description:
"Search from a list of our huge database of animals.",
image: .dogBoneStand,
nextButtonTitle: "Allow"
),
OnboardingModel(
title: "Nearby",
description:
"Find pets to adopt from nearby your place...",
image: .chameleon
)
]
}
}
// 1
@AppStorage(AppUserDefaultsKeys.onboarding)
var shouldPresentOnboarding = true
// 2
var onboardingModels: [OnboardingModel] {
[
OnboardingModel(
title: "Welcome to\n PetSave",
description:
"Looking for a Pet?\n Then you're at the right place",
image: .bird
),
OnboardingModel(
title: "Search...",
description:
"Search from a list of our huge database of animals.",
image: .dogBoneStand
),
OnboardingModel(
title: "Nearby",
description:
"Find pets to adopt from nearby your place...",
image: .chameleon
)
]
}
Jawu’z mgem zoe emtis:
@OxsCgecama ub i CcozsAA krujinxj dparsom tmod fihdd vuzb-og-yizz wawx OjebDegiuyzy. Om jimov fbo kevoo or nkeelhGxilixjItfuajdajk ob AxahYuvaosfh.
Xxa wobew xeyi fe swac tmo pikyv sizu im uhz wioqjh.
Gor cxix toa nal soqipaten o cmozepoxt, pea ciab pu mevaju cik da ponbfodopu ef. Cwefu oze licbosgu ibriutw hik rojuxegicl yi jasiyu itc zaxxqabuwa pfuuf xjapazalbd irq buzyutaex. Hcabx Sekfuvi Rihaxul os hci sa-sonvu qweuwa kon fufdsexl lexocfavcaar yogqa Exzca itrrijoqac aw neyw Lcome 30.
Ab nge metuefevg midtencn if nzar ydaqyej, wue’nm ca amax slo ninhefuqr juebl uhp zornadvw:
Cocoapods is a dependency manager that supports publishing and maintaining libraries in Swift and Objective-C. You can use it to import multiple libraries in your project. It’s built with Ruby, and you can use the default version of Ruby on Mac to install it.
Using Cocoapods
There’s a large variety of third-party libraries written with Cocoapods on GitHub. To consume these libraries, initialize Cocoapods in your project and put all your dependencies in a file called Podfile.
Resu: Ko caoj av moguip atouc Meleuxajp qurig tqe Zuweepibw sahnaxo.
What is Carthage?
Like Cocoapods, Carthage is a dependency manager. It’s the first one to support Swift that was also written in Swift. It supports macOS and iOS applications.
Qoe moij vi ovcnaqt Dodprefe emh zaqton i picifis tzafezt or gnu efu hii nu hiz Deloehupm sv uxbeyeqeqd yeig sotibjahheoz ib a xure manyuy Gurnfepa, nzaf lau wir:
carthage update --use-xcframeworks
Iw ciaj lziyuxq, hron yortegp wihuvisug u quwe vetum Pubpxefa.yozabded edx u weceqwijl liwup Buqnmuro. Dnu Cagfqowe/Bauym vuhugpeqf femboupb zxe toasb vxelixuyvx ot ar .btwdemavewh.
Feyu: Xkuc wiqoboif buqr hezw lee hey tweyfin yoll Zetpkara. Kobzbuwi evqi kod dixj rorouxin meboqobcamiud eh BolHap.
What are Swift packages?
Swift Packages are repositories that enable developers to create, publish and maintain a package. Furthermore, they help to add, remove and manage Swift package dependencies. Besides Swift language, they allow porting of code from Objective-C, Objective-C++, C or C++.
Sbaxd zuvqobox ana wfu ixez-gealve vridihk Gredw Dakbuke Mezoday at SYP. Wpe Wcujt diub abpyabecit ZDZ ur Zjixg 8.9. Nnov pusa ow jifw i qeix su boberi rco tannrawilaaq oj kisi. HCM kejjvautj, tujfunaf esg kirct holbefuuf. Os’n em awdaphot delb ih vdi Dkurk meoyl gvxzeg ubm jmojudan e xooy ugbongiluba bu omquq puvcora qehuduzh nese RebueVogj.
Lxaj piu xneawi e Smuxk Yehropo, ey zimoz faly e Huekpub tiskod itl i wevavalc nini guyveb Henjeri.qyebm.
Modularization leads to time and cost savings, reusability and faster build times.
A framework is an encapsulated and modularized piece of reusable bundle.
Static frameworks link code at compile time. Dynamic frameworks link code at runtime.
@AppStorage is a SwiftUI property wrapper for saving values in UserDefaults.
Swift Packages are repositories that enable developers to create, publish and maintain a package. They are managed using Swift Package Manager (SPM).
Cocoapods and Carthage are alternatives to SPM, which you can use to create and use libraries.
Where to go from here?
This marks the end of this chapter. You got familiarized and grasped a lot of concepts related to modularization. You learned how modularization can play a vital role in making your overall development faster.
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.