{"id":57782,"date":"2023-07-26T12:27:23","date_gmt":"2023-07-26T06:57:23","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=57782"},"modified":"2023-08-01T12:42:32","modified_gmt":"2023-08-01T07:12:32","slug":"modularise-your-app-with-swift-package-manager-spm","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/modularise-your-app-with-swift-package-manager-spm\/","title":{"rendered":"Modularise your app with Swift Package Manager (SPM)"},"content":{"rendered":"<h2><span style=\"font-weight: 400;\">Introduction<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">SPM &#8211; <\/span><b>Swift Package Manager<\/b><span style=\"font-weight: 400;\"> is a tool for managing the distribution of Reusable Swift code. With the term <\/span><b>\u2018Distribution\u2019<\/b><span style=\"font-weight: 400;\"> there comes a question of how to distribute. <\/span><span style=\"font-weight: 400;\">The answer is <\/span><b>Package. <\/b><\/p>\n<p><span style=\"font-weight: 400;\">It\u2019s nothing new as we are already using some third-party, open-source code or writing our reusable, distributable code with the help of some Dependency managers like <\/span><b>CocoaPods<\/b><span style=\"font-weight: 400;\">, and <\/span><b>Carthage<\/b><span style=\"font-weight: 400;\">. <\/span><span style=\"font-weight: 400;\">But with <\/span><b>SPM<\/b><span style=\"font-weight: 400;\"> it is very easy to do that. <\/span><\/p>\n<p><b>SPM<\/b><span style=\"font-weight: 400;\"> has come a long way since it was introduced with Swift 3.0 but was restricted to server-side applications. Since the release of Xcode 11 and Swift 5, it\u2019s available for iOS development. <\/span><span style=\"font-weight: 400;\">Using it in your project is highly recommended as it has many benefits.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Why should I use <\/span><b>SPM<\/b><span style=\"font-weight: 400;\">?<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Easy to adapt, in-built with Xcode.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Improve build time.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Easy to add third-party\/open-source dependencies.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Help to easily <\/span><b>modularise<\/b><span style=\"font-weight: 400;\"> your app code.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Easy distribution of reusable components\/modules.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Independent of CPU architecture of Open Libraries (<\/span><i><span style=\"font-weight: 400;\">Overcome the issue seen for cocoa pods library built with intel processor were not working on M1 machine<\/span><\/i><span style=\"font-weight: 400;\">).\u00a0<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">There are more reasons to adopt SPM but the above should be enough to motivate us to use SPM in our code.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Every developer cares about writing clean code and tries to modularise code with folder structure, some developers use advanced techniques like local <strong>Cocoa pods<\/strong>, <strong>Carthage<\/strong>, and <strong>XCFramework<\/strong>. These are good techniques but are third-party dependency managers with some cumbersome steps to maintain the module\/library except XCFramework. <\/span><span style=\"font-weight: 400;\">With SPM it is very easy to create modules as library type in <\/span><b>Packages<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Lets us see how we may apply <\/span><a href=\"https:\/\/increment.com\/mobile\/microapps-architecture\/\"><span style=\"font-weight: 400;\">microapp architecture<\/span><\/a><span style=\"font-weight: 400;\"> to modularise our application code using SPM.<\/span><\/p>\n<p><b>What we will learn in this blog:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Modularise app code using SPM local package.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">How to publish our package.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Add Dependency to a package.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Add remote packages.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Use the cocoa pods library and SPM package in the same project.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">The first step of modularization is identifying the candidate module, it may be UI-related, Networking module, App Navigation module, or any Utility module. <\/span><span style=\"font-weight: 400;\">To reduce the complexity and to adhere to our topic I identify simple dummy <\/span><b>MyAppColorKit<\/b><span style=\"font-weight: 400;\">, <\/span><b>MyAppFontKit, <\/b><span style=\"font-weight: 400;\">and the <\/span><b>Networking layer<\/b><span style=\"font-weight: 400;\"> as possible modules.\u00a0<\/span><\/p>\n<p><b>MyAppColorKit<\/b><span style=\"font-weight: 400;\"> and <\/span><b>MyAppFontKit<\/b><span style=\"font-weight: 400;\"> are just UI Utility modules required to maintain the design style of the app. Mostly we keep such classes bundled with app and app extension. But by modularising it we can share it among many targets in our project or across many projects. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">Though these are not the best example of modularisation but will justify the concept.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Steps:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Create Swift Package.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Configure <\/span><span style=\"font-weight: 400;\">Package.swift<\/span><span style=\"font-weight: 400;\"> manifest<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Add code files to the source folder.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Use of appropriate access specifiers.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Add Package to the main project.<\/span><\/li>\n<\/ol>\n<p><b>Create Swift Package:<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Start <\/span><b>Xcode<\/b><span style=\"font-weight: 400;\"> and create a new package by selecting <\/span><b>File&gt;&gt;New&gt;&gt;Package<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<div id=\"attachment_57764\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57764\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57764 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage1-1024x583.png\" alt=\"\" width=\"625\" height=\"356\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage1-1024x583.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage1-300x171.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage1-768x437.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage1-624x355.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage1.png 1318w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-57764\" class=\"wp-caption-text\">Create Package using Xcode<\/p><\/div>\n<p><span style=\"font-weight: 400;\">Name your package, I have used <\/span><b>MyAppKit<\/b><span style=\"font-weight: 400;\"> to resonate with Apple\u2019s other SDK naming standard.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Keep the source control checked to keep our package under version control as SPM has version requirements following <\/span><a href=\"https:\/\/semver.org\/\"><span style=\"font-weight: 400;\">semantic versioning<\/span><\/a><span style=\"font-weight: 400;\">. <\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-57765 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage2-1024x615.png\" alt=\"\" width=\"625\" height=\"375\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage2-1024x615.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage2-300x180.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage2-768x462.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage2-1536x923.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage2-624x375.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage2.png 1594w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">That is all we do to create a minimal local swift package named <\/span><b>MyAppKit<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Now check the folder and files Xcode created by default for us.\u00a0<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">README &#8211; Provide a possible description of the package.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Package.swift<\/span><span style=\"font-weight: 400;\"> &#8211; Describes the configuration of the swift package.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Source Folder &#8211; Contains the source file in a sub-folder scoped per target.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Tests Folder &#8211; Contains XCTest test cases in [TargetName]Tests subfolder scoped per target.\u00a0<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Of these, the most important is the <\/span><span style=\"font-weight: 400;\">Package.swift<\/span><span style=\"font-weight: 400;\">. It declares the complete structure of our Package.<\/span><\/p>\n<div id=\"attachment_57766\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57766\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57766 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage3-1024x503.png\" alt=\"\" width=\"625\" height=\"307\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage3-1024x503.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage3-300x147.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage3-768x377.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage3-1536x754.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage3-2048x1006.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/CreatePackage3-624x306.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-57766\" class=\"wp-caption-text\">Package.swift<\/p><\/div>\n<p><span style=\"font-weight: 400;\">Let us break down and understand the <\/span><b>Package.swift<\/b> <span style=\"font-weight: 400;\">file.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">The first line,<\/span><span style=\"font-weight: 400;\">\/\/ swift-tools-version: 5.8 <\/span><span style=\"font-weight: 400;\">states the minimum version of Swift required for this package to be built.<\/span><\/li>\n<li style=\"font-weight: 400;\"><em><span style=\"font-weight: 400;\">import PackageDescription <\/span><\/em><span style=\"font-weight: 400;\">imports the <\/span><a href=\"https:\/\/developer.apple.com\/documentation\/PackageDescription\/Package\"><span style=\"font-weight: 400;\">PackageDescription<\/span><\/a><span style=\"font-weight: 400;\"> framework required to define the package.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Next, Pass a name to the Package class the name of your Package.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Products are the targets this package will build and produce. These can be either a <\/span><i><span style=\"font-weight: 400;\">library<\/span><\/i><span style=\"font-weight: 400;\">, code which can be imported into other Swift projects, or an <\/span><i><span style=\"font-weight: 400;\">executable code<\/span><\/i><span style=\"font-weight: 400;\"> that can be run by the operating system.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Next, we define the dependencies this package requires.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Finally, the targets, it is an array of targets and test targets. There are many versions of the target declaration available. We may opt as per use.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">All the source codes are kept in <strong>Sources &gt;&gt; TargetNamed_Subfolder<\/strong> (Same name as target).<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">For more information on <\/span><em><span style=\"font-weight: 400;\">Package.swift<\/span><\/em><span style=\"font-weight: 400;\"> please check out <\/span><a href=\"https:\/\/www.swift.org\/package-manager\/\"><span style=\"font-weight: 400;\">Swift.org &#8211; Package Manager<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><b>Configure Swift <\/b><b>Package.swift<\/b><b> Manifest:<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Next, We\u2019ll configure the <\/span><em><span style=\"font-weight: 400;\">Package.swift<\/span><\/em><span style=\"font-weight: 400;\"> to create two products<\/span> <b>MyAppColorKit <\/b><span style=\"font-weight: 400;\">and <\/span><b>MyAppFontKit<\/b><span style=\"font-weight: 400;\"> vending them as libraries.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This means we will be able to import <\/span><b>MyAppColorKit <\/b><span style=\"font-weight: 400;\">and<\/span><b> MyAppFontKit <\/b><span style=\"font-weight: 400;\">as libraries in our project. <\/span><span style=\"font-weight: 400;\">As described above all the source code files reside in the subfolder of the Sources directory having the same name as the target they belong to, and test cases to the respective subfolder in the Tests directory.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">We <\/span><b>add source code files<\/b><span style=\"font-weight: 400;\"> and end up as shown in this figure.<\/span><\/p>\n<div id=\"attachment_57767\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57767\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57767 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage1-1024x544.png\" alt=\"\" width=\"625\" height=\"332\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage1-1024x544.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage1-300x159.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage1-768x408.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage1-1536x816.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage1-2048x1088.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage1-624x332.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-57767\" class=\"wp-caption-text\">Configure Package<\/p><\/div>\n<p><span style=\"font-weight: 400;\">The configured <\/span><b>Package.swift<\/b> <span style=\"font-weight: 400;\">should have been well understood by earlier explained steps except for the dependency declared on the <\/span><b>MyAppColorKit <\/b><span style=\"font-weight: 400;\">target<\/span> <span style=\"font-weight: 400;\">of <\/span><b>MyAppFontKit.<\/b><\/p>\n<p><span style=\"font-weight: 400;\">It just makes sure that <\/span><b>MyAppFontKit <\/b><span style=\"font-weight: 400;\">is accessible in <\/span><b>MyAppColorKit <\/b><span style=\"font-weight: 400;\">but not the other way around. <\/span><span style=\"font-weight: 400;\">Feel free to check out the <\/span><a href=\"https:\/\/github.com\/ankittlp\/IntegratorValidator.git\"><span style=\"font-weight: 400;\">code<\/span><\/a><span style=\"font-weight: 400;\"> in <\/span><b>MyAppFontKit <\/b><span style=\"font-weight: 400;\">and <\/span><b>MyAppColorKit.<\/b><i><span style=\"font-weight: 400;\"> (They are just dummy code to explain the modularity approach don\u2019t forget to check on the <\/span><\/i><b><i>access specifier<\/i><\/b><i><span style=\"font-weight: 400;\">)<\/span><\/i><\/p>\n<p><span style=\"font-weight: 400;\">At this point, if you check the schemes in your Package project you will find that Xcode has created schemes for each product and an additional scheme with the name <\/span><b>[PackageName]-Package<\/b><span style=\"font-weight: 400;\"> to build all targets and run all unit test cases.<\/span><\/p>\n<p><div id=\"attachment_57768\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57768\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57768 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage2-1024x576.png\" alt=\"\" width=\"625\" height=\"352\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage2-1024x576.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage2-300x169.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage2-768x432.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage2-1536x864.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage2-2048x1152.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/ConfigurePackage2-624x351.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-57768\" class=\"wp-caption-text\">[PackageName]-Package scheme<\/p><\/div><b>Add Package Dependencies to our Project :<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Now we will add <strong>MyAppKit<\/strong> package to our project.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Go to <\/span><b>Xcode &gt;&gt; File &gt;&gt; AddPackages &gt;&gt; Add Local &gt;&gt; AddPackage <\/b><span style=\"font-weight: 400;\">to select the Package directory locally. For AddToProject, select your Project, not the Pod project if we have Pods dependency also in our project.<\/span><\/p>\n<div id=\"attachment_57769\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57769\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57769 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage1-1024x579.png\" alt=\"\" width=\"625\" height=\"353\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage1-1024x579.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage1-300x170.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage1-768x434.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage1-1536x868.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage1-2048x1158.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage1-624x353.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-57769\" class=\"wp-caption-text\">1. Add local package<\/p><\/div>\n<div id=\"attachment_57770\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57770\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57770 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage2-1024x568.png\" alt=\"\" width=\"625\" height=\"347\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage2-1024x568.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage2-300x166.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage2-768x426.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage2-1536x852.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage2-2048x1136.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage2-624x346.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-57770\" class=\"wp-caption-text\">2. Add local package<\/p><\/div>\n<p><span style=\"font-weight: 400;\">The final step before importing and implementing the <\/span><b>MyAppColorKit <\/b><span style=\"font-weight: 400;\">and<\/span><b> MyAppFontKit <\/b><span style=\"font-weight: 400;\">is to add libraries to your app target from the target\u2019s setting in the General tab under <\/span><b>Frameworks, Libraries, and Embedded Content<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<div id=\"attachment_57771\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57771\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57771 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage3-1024x755.png\" alt=\"\" width=\"625\" height=\"461\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage3-1024x755.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage3-300x221.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage3-768x567.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage3-1536x1133.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage3-624x460.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage3.png 1914w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-57771\" class=\"wp-caption-text\">Embed framework<\/p><\/div>\n<p><span style=\"font-weight: 400;\">Just import the libraries in your implementation.<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-57772 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage4-1024x65.png\" alt=\"\" width=\"625\" height=\"40\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage4-1024x65.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage4-300x19.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage4-768x49.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage4-624x40.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddPackage4.png 1224w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">We saw how easily, with SPM\u2019s local package we were able to modularize our project code. <\/span><span style=\"font-weight: 400;\">Using this technique, we may want to segregate our code into micro apps modules that can stand alone.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Benefits of modularising code with SPM:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Easy to implement and maintain modularity compared to local cocoa pods.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">The local library can be edited in the project itself.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Improved build time as only changed modules will build again.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Different team members can work on their modules without interfering with each other.<\/span><\/li>\n<\/ul>\n<p><b>Publishing Package :<\/b><\/p>\n<p><span style=\"font-weight: 400;\">We saw how we used the local package in our project. Following the same approach, I created a new networking package <\/span><b>ANNetwork <\/b><span style=\"font-weight: 400;\">locally while in development.<\/span><\/p>\n<div id=\"attachment_57773\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57773\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57773 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage1-1024x687.png\" alt=\"\" width=\"625\" height=\"419\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage1-1024x687.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage1-300x201.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage1-768x515.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage1-1536x1031.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage1-2048x1375.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage1-624x419.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-57773\" class=\"wp-caption-text\">ANNetwork Package in development<\/p><\/div>\n<p><span style=\"font-weight: 400;\">Now, let us publish <\/span><b>ANNetwork<\/b><span style=\"font-weight: 400;\"> as an open-source remote Swift<\/span> <span style=\"font-weight: 400;\">Package. Remote packages are easily made available as dependencies using <\/span><b>SPM.<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Publishing your package is just like creating and hosting a remote repository and tagging it following <\/span><a href=\"https:\/\/semver.org\/\"><span style=\"font-weight: 400;\">semantic versioning<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Feel free to use <strong>Xcode<\/strong>, <strong>command line<\/strong>, or any other tool to create a remote repository on any git-based code hosting repository services like <strong>GitHub<\/strong>, <strong>GitLab<\/strong>, or <strong>BitBucket<\/strong>. <\/span><span style=\"font-weight: 400;\">I prefer to use <\/span><b>Sourcetree<\/b><span style=\"font-weight: 400;\"> to manage Git Repository, but for better reach showing the steps using Xcode to create the remote repository and <\/span><b>tag<\/b><span style=\"font-weight: 400;\"> it once the stable usable library version is complete for publishing.<\/span><\/p>\n<div id=\"attachment_57774\" style=\"width: 310px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57774\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57774 size-medium\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage2-300x264.png\" alt=\"\" width=\"300\" height=\"264\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage2-300x264.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage2-768x676.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage2-624x549.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage2.png 986w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-57774\" class=\"wp-caption-text\">Publish Remote Package<\/p><\/div>\n<div id=\"attachment_57775\" style=\"width: 310px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57775\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57775 size-medium\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage3-300x153.png\" alt=\"\" width=\"300\" height=\"153\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage3-300x153.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage3-768x392.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage3-624x318.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage3.png 1000w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-57775\" class=\"wp-caption-text\">Tag Remote Package<\/p><\/div>\n<p><span style=\"font-weight: 400;\">That\u2019s it, <\/span><b>ANNetwork<\/b><span style=\"font-weight: 400;\"> Swift Package is live and available to use as Remote Dependency.<\/span><\/p>\n<div id=\"attachment_57776\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57776\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57776 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage4-1024x506.png\" alt=\"\" width=\"625\" height=\"309\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage4-1024x506.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage4-300x148.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage4-768x380.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage4-1536x760.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage4-2048x1013.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/PublishPackage4-624x309.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-57776\" class=\"wp-caption-text\">Published Remote ANNetwork Package<\/p><\/div>\n<p><span style=\"font-weight: 400;\">Now we can remove the <\/span><b>ANNetwork<\/b><span style=\"font-weight: 400;\"> local package.<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-57777\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage1-201x300.png\" alt=\"\" width=\"201\" height=\"300\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage1-201x300.png 201w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage1-685x1024.png 685w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage1-624x933.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage1.png 768w\" sizes=\"(max-width: 201px) 100vw, 201px\" \/> <img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-57778\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage2-240x300.png\" alt=\"\" width=\"240\" height=\"300\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage2-240x300.png 240w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage2.png 530w\" sizes=\"(max-width: 240px) 100vw, 240px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Removing the local package is as easy as removing any other file. Just make sure to <\/span><b>Remove Reference,<\/b><span style=\"font-weight: 400;\"> not Move to Trash.<\/span><\/p>\n<p><b>Add Remote Package:<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Adding a Remote package is the same as adding a local package, but the only difference is we need the Git url of the Remote package.<\/span><\/p>\n<div id=\"attachment_57780\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57780\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57780 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage3-1024x574.png\" alt=\"\" width=\"625\" height=\"350\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage3-1024x574.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage3-300x168.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage3-768x430.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage3-1536x861.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage3-2048x1148.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/AddRemotePackage3-624x350.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-57780\" class=\"wp-caption-text\">Add Remote Package.<\/p><\/div>\n<p><span style=\"font-weight: 400;\">Set the dependency rule specified \u201c<\/span><b>Up to Next Major Version<\/b><span style=\"font-weight: 400;\">\u201d. That means it will add the available version between 1.0.0 to Next Major Version, and <\/span><b>Update Package<\/b><span style=\"font-weight: 400;\"> will migrate the library to <\/span><b>Up to Next Major. <\/b><span style=\"font-weight: 400;\">Compile the project now, It will run as earlier with no difference.<\/span><\/p>\n<p><b>Publish Private Package:<\/b><\/p>\n<p><span style=\"font-weight: 400;\">We saw how easy it is to publish and distribute a public package. In some projects, we may have a private package<\/span> <span style=\"font-weight: 400;\">only to be used at the organization level or project level. A package with these restrictions can be published with Private Git Repository and used with proper <\/span><a href=\"https:\/\/docs.github.com\/en\/authentication\/connecting-to-github-with-ssh\/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent\"><b>SSH keys<\/b><\/a><span style=\"font-weight: 400;\"> setup or repository-level shared <\/span><b>Personal Access Token<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><b>SPM in CocoaPods-based Project:<\/b><\/p>\n<p><span style=\"font-weight: 400;\">There are still a few dependencies that are only available on cocoa pods. For similar cases where we need to use SPM in a cocoa pods-based project. Please check this<\/span><a href=\"https:\/\/github.com\/ankittlp\/IntegratorValidator.git\"><span style=\"font-weight: 400;\"> sample project<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It has a dependency named <\/span><b>ANValidator<\/b><span style=\"font-weight: 400;\"> which is available on cocoa pods. So, to add SPM dependencies, I selected the <\/span><b>IntegratorValidator<\/b><span style=\"font-weight: 400;\"> Project, not the <\/span><b>Pods <\/b><span style=\"font-weight: 400;\">project.<\/span><\/p>\n<div id=\"attachment_57781\" style=\"width: 924px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-57781\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-57781 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/SPM_With_Pods.png\" alt=\"\" width=\"914\" height=\"334\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/07\/SPM_With_Pods.png 914w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/SPM_With_Pods-300x110.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/SPM_With_Pods-768x281.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/07\/SPM_With_Pods-624x228.png 624w\" sizes=\"(max-width: 914px) 100vw, 914px\" \/><p id=\"caption-attachment-57781\" class=\"wp-caption-text\">SPM with Cocoa pods<\/p><\/div>\n<p><span style=\"font-weight: 400;\">I\u2019ll end up here with the motivation to write more on Swift and iOS technology.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Do try SPM in your next project. Subscribe to our blogs for more insights.\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<div class=\"ap-custom-wrapper\"><\/div><!--ap-custom-wrapper-->","protected":false},"excerpt":{"rendered":"<p>Introduction SPM &#8211; Swift Package Manager is a tool for managing the distribution of Reusable Swift code. With the term \u2018Distribution\u2019 there comes a question of how to distribute. The answer is Package. It\u2019s nothing new as we are already using some third-party, open-source code or writing our reusable, distributable code with the help of [&hellip;]<\/p>\n","protected":false},"author":1138,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":650},"categories":[1400],"tags":[5284,2715,5283],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/57782"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1138"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=57782"}],"version-history":[{"count":6,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/57782\/revisions"}],"predecessor-version":[{"id":57869,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/57782\/revisions\/57869"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=57782"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=57782"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=57782"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}