How Swift Packages Changed the Way I Build?Apps

How Swift Packages Changed the Way I Build?Apps

Introduction

Even though we had dependencies managers for several years now, with Swift Package Manager (SPM) creating packages in your app is almost as easy as adding new folders. Convert parts in your project to packages is not just a way to organize your code nicely; it actually changes the way you work and architect your app. 

It all started when I had to take an existing, big project, and port one feature to a dedicated app. Since this feature is based on a low-level code such as Networking, Persistent Store, Analytics, and Logging, I thought it would be best to check how to convert those parts to modules.

I planned to:

  • Copy all these code to the new app.
  • Organize the code in Swift Packages.
  • Take the packages and implement them back into the “mother” app.
  • Put the packages on their own repositories in GitHub and have shared code.

I knew that having a shared code between apps is a great way to maintain them over time. What I didn’t realize that even without putting those packages on Github and share them, using Modules (Packages/Pods, whatever you want to call it) brings additional value to your app.

Playing with Lego

Most standard iOS apps are built from one big codebase and some third-party libraries.  Organize your code to packages changes all that. It makes your app development process feels like playing with Lego bricks. Do you want an app with the same foundation but a different UI? No problem, easy to setup. You want the Today Widget to take advantage of the excellent Logging mechanism you created? Piece of cake. Everything is modular and easy to maintain.

Take a look at the following diagram:

No alt text provided for this image

Except for the UI, all the other components are, in fact, packages. The diagram also reflects the dependencies between them. The Logger and some help methods bundles to a Common library are the low layer of the project. They do not depend on anything, but the other packages need them. So, we have a network and persistent store packages that require the common and the logger modules to function. 

Then we move to the sync (that obviously needs the network and the persistent store) and so on with the other modules.

Now, if you built one or two apps in your life, this diagram is not new. Most apps actually built like that, but with groups. With modules, it’s more clear and transparent. 

Modules make your layers interface clearer

Because each part in your app is a module, the process of building them forces you to really plan and design your interfaces between them. You need to make important design decisions, and you need to decide what functions are public (Oh, finally, it has meaning inside your app!), and what are the dependencies. By looking at the diagram above, you cannot import the Analytics package into the Persistent Store Library. I’m not sure It’s even possible, but surely, it’s not a best practice. 

Actually, without drawing the diagram, it’s hard to define the dependencies, so we also earned... a diagram?

You now have several small problems instead of a giant one

This is part of something called “Dynamic Programming”. Everybody knows that solving a small problem is easier than solving a big one. Splitting your app to small modules makes it easier for you to solve issues in your code.

In fact, your app can be in a state that it’s not even compiled (!), and you can still work on a specific module, compile it, writing tests, and make any modifications you want. It’s also clear on what part of your app you need to work, now that your project is built of SDKs.

Compiling is so fast now that it’s ridicules 

You know when you do a small change, and then you wait 30-40 seconds for your project to compile? Well, those days are (almost) over. 

As I just mentioned – you can compile a specific module, and oh man, it is so fast you do it again just to make sure something actually happened. Compile a particular module is easy – just select it from the scheme popup menu:

No alt text provided for this image

I don’t think I need to explain why compile-time has a significant impact on your daily life as a developer. There’s no way to go back.

It’s straightforward to test everything now, even your Apple Watch Extension

And this is a continuation to the previous point – the benefit of separation is not only compiled time, but it’s also testing. 

Every module has its own tests:

No alt text provided for this image

The fact that the tests are located just below the execution code, plus the fast compilation, encourages you to add a lot of tests to your app (module). Heck, sometimes it’s the only way to check that your module works since, in many cases, you do it when your app doesn’t even compile.

Also, it’s the only way to test an Apple Watch– through its modules.

So, what about the actual app tests? Well, now that you have independent modules, which being tested internally, you can start doing something called “Integration Tests” – test how your modules work together. 

Remember - when you share your package with another app, its tests go with it. So it’s another something you save – some of the tests for the new app.

And yes, it’s effortless to share code.

After all, the main reason for a swift package is to share code between projects. Look at the dependencies from the manifest file:

No alt text provided for this image

You see? You can define a dependency as a local package, or download it from Git. You can just upload your package to GitHub, change the manifest, and you’re done! 

SPM (Swift Package Manager) has its drawbacks

SPM still has its drawbacks – 

-       You cannot add any resource files to your package. Not even a Xib file. It means that building UI has to be from code and building a persistent store library based on Core Data might be an issue, since Core Data needs to make use of the Model file (Although you can bypass it somehow).  Swift 5.3 is planned to solve it.

-       A Swift Package can be depended on another Swift Package. Not Pods or your app code. The problem is that not all the essential frameworks have support for SPM, so you need to solve it somehow using delegates or closures.

If those are big issues for you, there are other ways of creating swift packages.

Summary

Swift Package Manager has a way to go to be usable and functional as Cocoapods or Carthage. But Xcode 11 makes it so easy that it makes no sense not to use it. Some of the things I wrote are also true for Cocoapods and Carthage; after all, the principles stay the same. No matter what you use, structure your app with modules is always recommended.  

great article!

amazing article! I love Swift Packages.

要查看或添加评论,请登录

Avi Tsadok的更多文章

  • Boost Your Loop Performance By 87%

    Boost Your Loop Performance By 87%

    Today’s devices are incredibly powerful, often leading us to overlook the importance of efficiency and optimizations…

    2 条评论
  • Explore the Dynamic Island — ActivityKit Tutorial

    Explore the Dynamic Island — ActivityKit Tutorial

    Apple wowed us with the iPhone 14 Pro presentation in a way no one expected. The team from Cupertino took a hardware…

    1 条评论
  • Where Is My?Logic?

    Where Is My?Logic?

    “Describe to me your app architecture”. “Oh, it’s easy.

    2 条评论
  • Swift Result Builders – A Giant Leap Forward to produce a beautiful code

    Swift Result Builders – A Giant Leap Forward to produce a beautiful code

    The most noticeable thing about SwiftUI is that it looks incredible. It takes a relatively big chunk of code and…

    6 条评论
  • Swift 5.7: Unwrapping Optionals Gets Improvement

    Swift 5.7: Unwrapping Optionals Gets Improvement

    Introduction Unwrapping optional variables in Swift is one of the most common development tasks iOS developers perform…

    4 条评论
  • Creating a Custom Core Data Store

    Creating a Custom Core Data Store

    This tutorial is a special one. Its primary goal is to unleash how Core Data works under the hood, not to solve you a…

  • How Apple Screwed Up with SwiftUI and Core Data

    How Apple Screwed Up with SwiftUI and Core Data

    Introduction A few months ago, I decided that my third iOS development book will focus on Core Data, which is Apple’s…

    2 条评论
  • My Personal Takes from Using Combine

    My Personal Takes from Using Combine

    Confession I have a confession I want to begin with — before adopting any new technology or design pattern, I need to…

  • Reorder Items in SwiftUI LazyVStack

    Reorder Items in SwiftUI LazyVStack

    Introduction Those of you who are familiar with UIKit iOS 11 Drag and Drop API probably know that it dramatically…

  • UIKit Animations Are Messy. Here's Why SwiftUI May Fix It.

    UIKit Animations Are Messy. Here's Why SwiftUI May Fix It.

    Not only do iOS animations feel and look great, but they are also very easy to create.So how come I have the nerve to…

社区洞察

其他会员也浏览了