{"id":5116,"date":"2022-02-22T13:18:33","date_gmt":"2022-02-22T05:18:33","guid":{"rendered":"http:\/\/123.57.164.21\/?p=5116"},"modified":"2022-02-23T15:04:22","modified_gmt":"2022-02-23T07:04:22","slug":"swift-libraries-frameworks-swift-packagewhats-the-difference","status":"publish","type":"post","link":"https:\/\/92it.top\/?p=5116","title":{"rendered":"Swift Libraries, frameworks, swift package What\u2019s the difference?"},"content":{"rendered":"\n<p>Every developer knows how important to support clean architecture in the project. Reasons for preference modular codebase to monolith app obvious. They are namespacing, access controls, using different programming languages in different modules. And, of course, code reuse.<\/p>\n\n\n\n<p>In this article, we will talk about options to support modular codebase in iOS Swift-based project with:<\/p>\n\n\n\n<ul><li>ibraries;<\/li><li>frameworks, including new XCFramework bundle type;<\/li><li>Swift packages.<\/li><\/ul>\n\n\n\n<p id=\"9be0\">Although the review is limited to iOS only, this doesn\u2019t mean that you can\u2019t use these approaches for other Apple\u2019s platforms.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"28a8\">Basics<\/h4>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p id=\"396d\">The concept of code organization and access control in Swift based on <a href=\"https:\/\/swift.org\/package-manager\/\" rel=\"noreferrer noopener\" target=\"_blank\">Modules<\/a>. The module represented as a single unit of code distribution. Frameworks, libraries, swift packages and build targets treated in Xcode as a separate module. Each with its namespace and access controls. Module, usually, solves a particular problem. It can be reused in different situations.<\/p>\n\n\n\n<p id=\"523e\"><a href=\"https:\/\/developer.apple.com\/documentation\/foundation\/bundle\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>Bundle<\/strong><\/a> is a file directory with subdirectories inside. On iOS, bundles serve to conveniently ship related files together in one package \u2014 for instance, images, nibs, or compiled code. The system treats it as one file and you can access bundle resources without knowing its internal structure. Dylib that cannot be linked, only opened in runtime with dlopen()<\/p>\n\n\n\n<p id=\"6575\"><strong>Source file<\/strong> is single Swift source code file within a module.<\/p>\n\n\n\n<p id=\"d72d\"><strong>Executable<\/strong> \u2014 main binary for application.<\/p>\n\n\n\n<p id=\"1d1b\"><a href=\"https:\/\/en.wikipedia.org\/wiki\/Object_file#targetText=An%20object%20file%20is%20a,work%20like%20a%20shared%20library.\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>Object file<\/strong><\/a> \u2014 An object file is a file containing <a href=\"https:\/\/en.wikipedia.org\/wiki\/Object_code\" rel=\"noreferrer noopener\" target=\"_blank\">object code<\/a>, meaning relocatable format <a href=\"https:\/\/en.wikipedia.org\/wiki\/Machine_code\" rel=\"noreferrer noopener\" target=\"_blank\">machine code<\/a> that is usually not directly executable. An object file may also work like a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Shared_library\" rel=\"noreferrer noopener\" target=\"_blank\">shared library<\/a>.<\/p>\n\n\n\n<p id=\"72c1\"><a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Object_code\" target=\"_blank\"><strong>Object code<\/strong><\/a> \u2014 In computing, object code or object module is the product of a compiler. In a general sense object code is a sequence of statements or instructions in a computer language, usually a machine code language (i.e., binary or an intermediate language such as register transfer language).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"a525\">Libraries<\/h4>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p id=\"cb51\">In computer science, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Library_(computing)\" rel=\"noreferrer noopener\" target=\"_blank\">library<\/a> means collection of resources and code, compiled into one or more architecture. Working with iOS application you\u2019ll faced static and dynamic libraries. Let\u2019s take a look on what they are.<\/p>\n\n\n\n<p id=\"49da\"><a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/DeveloperTools\/Conceptual\/DynamicLibraries\/100-Articles\/OverviewOfDynamicLibraries.html\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>Static library<\/strong><\/a> \u2014 (*.a) ( <a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/DeveloperTools\/Conceptual\/DynamicLibraries\/100-Articles\/OverviewOfDynamicLibraries.html#\/\/apple_ref\/doc\/uid\/TP40001873-SW1\" rel=\"noreferrer noopener\" target=\"_blank\">static archive library, static linked shared library<\/a>) \u2014 collection or archive of object files. Static linker collects app compiled source code with library code into a single executable file, which loaded into memory in its entirety at runtime.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/958\/0*SeaXdw0XFQNos6Yl.png\" alt=\"\"\/><\/figure>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-53-1024x923.png\" alt=\"\" class=\"wp-image-5118\" width=\"415\" height=\"374\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-53-1024x923.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-53-300x271.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-53-768x693.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-53-830x748.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-53-230x207.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-53-350x316.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-53-480x433.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-53.png 1038w\" sizes=\"(max-width: 415px) 100vw, 415px\" \/><\/figure><\/div>\n\n\n\n<p id=\"d5ab\">Since static library, in its general sense, is a sequence of statements or instructions in a machine code language, this is adding some limitations to create and distribute them:<\/p>\n\n\n\n<ul><li>You\u2019ll need to build a library for the same processor architecture as the client code. If you, for example, working on a library for the iOS application you will need to create a library for iOS Simulator and iOS devices.<\/li><li>The library can\u2019t include resource files: images, assets, nibs, strings file and other visual data. If you will include this resources to project them will be separate from .a file. Usually, as a solution to this problem, all relates external resources provided within another independent bundle.<\/li><\/ul>\n\n\n\n<p id=\"4bcd\">You can create a Swift static library, this is supported from Xcode 9.0. Till Xcode 9 dynamic frameworks where required. Developers, who were using CocoaPods remember that it was required to add <a href=\"http:\/\/blog.cocoapods.org\/CocoaPods-1.5.0\/\" rel=\"noreferrer noopener\" target=\"_blank\">use_frameworks<\/a>. It tells CocoaPods that you want to use Frameworks instead of Static Libraries since it wasn\u2019t supported for Swift. But fortunately Swift and Xcode are constantly improving and now we have support for Swift static libraries.<\/p>\n\n\n\n<p id=\"c93f\"><strong>Dynamic libraries<\/strong> (*.dylib) ( <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/DeveloperTools\/Conceptual\/DynamicLibraries\/100-Articles\/OverviewOfDynamicLibraries.html#\/\/apple_ref\/doc\/uid\/TP40001873-SW1\" target=\"_blank\">dynamic shared library, shared object, dynamically linked library<\/a>) are not copied into executable file, like static libraries. Instead, they are dynamically linked to at load or runtime, when both binary files and the library are in memory. Dynamic libraries stored and versioned separately. As a result, the dynamic library may be loaded not the same which was originally referenced if the update is considered binary compatible with the original version.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-54.png\" alt=\"\" class=\"wp-image-5119\" width=\"442\" height=\"385\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-54.png 970w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-54-300x262.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-54-768x670.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-54-830x724.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-54-230x201.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-54-350x305.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-54-480x419.png 480w\" sizes=\"(max-width: 442px) 100vw, 442px\" \/><\/figure><\/div>\n\n\n\n<p id=\"7980\"><mark>System iOS and macOS libraries are dynamic. This means that your app will receive improvements from Apple\u2019s updates without new build submission.<\/mark> This also may lead to issues with interoperability. That\u2019s why it is always a good idea to test the app on the new OS version before it becomes released.<\/p>\n\n\n\n<p id=\"24ea\">There are some old discussions related to the creation and integration of own custom .dylib for iOS app: <a href=\"https:\/\/stackoverflow.com\/questions\/48209855\/xcode-9-no-option-to-create-dylib-project-ios\" rel=\"noreferrer noopener\" target=\"_blank\">topic1<\/a>, <a href=\"https:\/\/stackoverflow.com\/questions\/4733847\/can-you-build-dynamic-libraries-for-ios-and-load-them-at-runtime\" rel=\"noreferrer noopener\" target=\"_blank\">topic2<\/a>. In spite of this Apples documents <a href=\"https:\/\/developer.apple.com\/library\/archive\/technotes\/tn2435\/_index.html#\/\/apple_ref\/doc\/uid\/DTS40017543-CH1-PROJ_CONFIG-APPS_WITH_DEPENDENCIES_BETWEEN_FRAMEWORKS\" rel=\"noreferrer noopener\" target=\"_blank\">clearly says<\/a>:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em>Dynamic libraries outside of a framework bundle, which typically have the file extension .dylib, are not supported on iOS, watchOS, or tvOS, except for the system Swift libraries provided by Xcode.<\/em><\/p><\/blockquote>\n\n\n\n<h4 class=\"wp-block-heading\">Frameworks<\/h4>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><a href=\"https:\/\/developer.apple.com\/library\/archive\/technotes\/tn2435\/_index.html#\/\/apple_ref\/doc\/uid\/DTS40017543-CH1-PROJ_CONFIG-APPS_WITH_DEPENDENCIES_BETWEEN_FRAMEWORKS\" rel=\"noreferrer noopener\" target=\"_blank\"><em>A framework<\/em><\/a><em> ( .framework): is a hierarchical directory that encapsulates a dynamic library, header files, and resources, such as storyboards, image files, and localized strings, into a single package. Apps using frameworks need to embed the framework in the app\u2019s bundle.<\/em><\/p><\/blockquote>\n\n\n\n<p id=\"97b9\">Frameworks intended for the same purposes as a <a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/MacOSX\/Conceptual\/BPFrameworks\/Concepts\/WhatAreFrameworks.html\" rel=\"noreferrer noopener\" target=\"_blank\">static and dynamic shared libraries<\/a>. But unlike libraries, frameworks:<\/p>\n\n\n\n<ul><li>can include resources like images, assets, documentations, strings files.<\/li><li>only one copy of framework read-only resource loaded to memory, that allows to decrease memory footprint and share framework between iOS app and extensions.<\/li><\/ul>\n\n\n\n<p id=\"db9d\">There is also another point of view on the difference between frameworks and libraries, which based on the architect and clean design perspective. In the great article \u201c <a href=\"https:\/\/martinfowler.com\/bliki\/InversionOfControl.html\" rel=\"noreferrer noopener\" target=\"_blank\">Inversion of Control<\/a>\u201d <a href=\"https:\/\/martinfowler.com\/\" rel=\"noreferrer noopener\" target=\"_blank\">Martin Fowler<\/a> says that inversion of control is a key part of what makes a framework different from a library:<\/p>\n\n\n\n<ul><li>The library is essentially a set of functions that you can call, these days usually organized into classes. Each call does some work and returns control to the client.<\/li><li>A Framework embodies some abstract design, with more behavior built in. In order to use it you need to insert your behavior into various places in the framework either by subclassing or by plugging in your own classes. The framework\u2019s code then calls your code at these points. The main control of the program is inverted, moved away from you to the framework.<\/li><\/ul>\n\n\n\n<p id=\"b307\">Frameworks supported from iOS 8.<\/p>\n\n\n\n<p id=\"7fe1\">Talking about frameworks also worth mentioning umbrella frameworks and universal frameworks (fat frameworks):<\/p>\n\n\n\n<p id=\"21d0\"><strong>umbrella framework:<\/strong> is a framework bundle that contains other frameworks. Umbrella frameworks available for <a href=\"https:\/\/developer.apple.com\/library\/mac\/documentation\/MacOSX\/Conceptual\/BPFrameworks\/Concepts\/FrameworkAnatomy.html#\/\/apple_ref\/doc\/uid\/20002253-97623-BAJJHAJC\" rel=\"noreferrer noopener\" target=\"_blank\">macOS apps<\/a>, but Apple <a href=\"https:\/\/developer.apple.com\/library\/archive\/technotes\/tn2435\/_index.html#\/\/apple_ref\/doc\/uid\/DTS40017543-CH1-PROJ_CONFIG-APPS_WITH_DEPENDENCIES_BETWEEN_FRAMEWORKS\" rel=\"noreferrer noopener\" target=\"_blank\">do not recommend<\/a> using them. Umbrella frameworks <a href=\"https:\/\/developer.apple.com\/library\/archive\/technotes\/tn2435\/_index.html\" rel=\"noreferrer noopener\" target=\"_blank\">are not supported on iOS, watchOS, or tvOS<\/a>.<\/p>\n\n\n\n<p id=\"f208\"><strong>universal framework (fat framework)<\/strong>: multi-architecture binary that contains code native to multiple instructions sets and can run on multiple processor types. In short, it contains code compiled for all the platforms which you are going to support. For example, x86_64 (64-bit Simulator), arm64 arm64e armv7 armv7s for devices. As a result, such a framework will have a larger size than a one-architecture framework. There are lots of tutorials on how to make universal framework using <a href=\"https:\/\/ss64.com\/osx\/lipo.html\" rel=\"noreferrer noopener\" target=\"_blank\">lipo<\/a>. This approach widely used for sharing a private binary. In this way, your framework consumer able work with your framework on a real device and simulator.<\/p>\n\n\n\n<p id=\"96ef\">You can expect framework with <code>file<\/code> command in Terminal:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">file &lt;PathToAppFramework>\/&lt;FrameworkName>.framework\/&lt;FrameworkName>\n<\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-55-1024x252.png\" alt=\"\" class=\"wp-image-5121\" width=\"557\" height=\"136\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-55-1024x252.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-55-300x74.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-55-768x189.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-55-830x204.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-55-230x57.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-55-350x86.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-55-480x118.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-55.png 1398w\" sizes=\"(max-width: 557px) 100vw, 557px\" \/><\/figure><\/div>\n\n\n\n<p>To inspect all the dynamically linked frameworks and libraries to a binary you can use <a rel=\"noreferrer noopener\" href=\"https:\/\/www.manpagez.com\/man\/1\/otool\/\" target=\"_blank\">otool<\/a>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">otool -L &lt;PathToArchive>\/Products\/Applications\/&lt;AppName>.app\/&lt;AppBinary>\n<\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-56-1024x846.png\" alt=\"\" class=\"wp-image-5122\" width=\"547\" height=\"451\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-56-1024x846.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-56-300x248.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-56-768x634.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-56-830x686.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-56-230x190.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-56-350x289.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-56-480x396.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-56.png 1402w\" sizes=\"(max-width: 547px) 100vw, 547px\" \/><\/figure><\/div>\n\n\n\n<p id=\"afe7\">Apple says that the app on average contains 100\u2013400 system dylibs. The loading of system frameworks is highly optimized. But loading custom embedded frameworks can be expensive. Apple\u2019s engineers encourage you to use frameworks wisely and limit the amount of used framework because it impacts on the app launch time. If you are interested in deep details on how the framework works and how it impacts on the app launch time, check the WWDC session <a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2016\/406\/\" rel=\"noreferrer noopener\" target=\"_blank\">Optimizing App Startup Time<\/a>.<\/p>\n\n\n\n<p id=\"1953\">This year Apple declare that Swift 5 provides binary compatibility for apps, that means that app built with one version of the Swift compiler will be able to talk to a library built with another version. Swift\u2019s ABI is currently declared <a rel=\"noreferrer noopener\" href=\"https:\/\/swift.org\/blog\/abi-stability-and-more\/\" target=\"_blank\">stable for Swift 5<\/a> on Apple platforms.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">XCFrameworks<\/h4>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p id=\"9da6\">XCFrameworks is a new supported way to distribute binary frameworks, available from Xcode 11. Actually a framework that now can containing code for multiple architectures and platforms. You will still be required to generate archives for different platforms and bundle them up together in single XCFrameworks. There is a great session from WWDC 2019: <a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2019\/416\/\" rel=\"noreferrer noopener\" target=\"_blank\">Binary Frameworks in Swift<\/a> that explain in detail how to create, integrate and distribute XCFrameworks.<\/p>\n\n\n\n<p id=\"41f5\">There are few advantages of using XCFrameworks:<\/p>\n\n\n\n<ul><li>XCFramework contain variants not only for device and Simulator, but for any of the platforms that Xcode supports: iOS, macOS, tvOS, watchOS;<\/li><li>It supports Swift and C-based code;<\/li><li>Can bundle up frameworks and static libraries.<\/li><\/ul>\n\n\n\n<p id=\"5d41\">With the new package manifest API in Xcode 12, it is now possible to make Swift packages that include one or more XCFrameworks. The details of implementation you can find in the official documentation <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.apple.com\/documentation\/swift_packages\/distributing_binary_frameworks_as_swift_packages\" target=\"_blank\">Distributing Binary Frameworks as Swift Packages<\/a> and <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2020\/10147\/\" target=\"_blank\">WWDC 2020 video<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Swift Package<\/h4>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p id=\"8af0\">Swift is a cross-platform language and requires a cross-platform tool for building the Swift code. One of the goals <a href=\"https:\/\/swift.org\/package-manager\/#targetText=The%20Swift%20Package%20Manager%20is,in%20Swift%203.0%20and%20above.\" rel=\"noreferrer noopener\" target=\"_blank\">Swift Package Manager<\/a> (SwiftPM) is simplified distribute source code in the Swift ecosystem. SwiftPM is an open-source project, you can find information about it on <a href=\"https:\/\/github.com\/apple\/swift-package-manager\" rel=\"noreferrer noopener\" target=\"_blank\">GitHub<\/a> as well.<\/p>\n\n\n\n<p id=\"251a\">Swift Package contains source files and manifest file (Package.swift). Manifest describes the configuration for the Swift package. Swift Package is defined and used with <a href=\"https:\/\/swift.org\/package-manager\/\" rel=\"noreferrer noopener\" target=\"_blank\">Swift Package Manager<\/a>, that included <a href=\"https:\/\/swift.org\/package-manager\/\" rel=\"noreferrer noopener\" target=\"_blank\">Swift 3.0 and above<\/a>. Because distribution in Source form, there is no need anymore to maintain binary compatibility for clients. So if you can ship the source code, then Swift Package is a great tool for you. With new changes in Xcode 11, you can easily create and distribute Swift Packages.<\/p>\n\n\n\n<p id=\"48bb\">Swift package consists of 3 parts: dependencies, targets and products:<\/p>\n\n\n\n<p id=\"64f7\"><strong>Dependencies<\/strong>: other swift packages, that you are using inside your package. In Package file each dependency specified by source location and version.<\/p>\n\n\n\n<p id=\"5bda\"><strong>Target<\/strong>: As Apple\u2019s document says, <a href=\"https:\/\/developer.apple.com\/documentation\/xcode\/creating_a_swift_package_with_xcode\" rel=\"noreferrer noopener\" target=\"_blank\">Targets are the basic building blocks of a package<\/a>. Is may be either a library or an executable as its product. Before Xcode 12 Swift package could contain only Swift, Objective-C\/C++, or C\/C++ files. Xcode 12 offers the new tools-version:5.3 which brings the new package manifest API. And now the Swift package can contain other resources types: images, storyboards, JSON files, Shell scripts, and much more. You can also localize those resources. That is great and desired improvement. Thank you to all who have contributed to making this available. Useful details and implementation details, you can find in the WWDC 2020 video <a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2020\/10169\/\" rel=\"noreferrer noopener\" target=\"_blank\">Swift packages: Resources and localization<\/a> and in documentation <a href=\"https:\/\/developer.apple.com\/documentation\/swift_packages\/localizing_package_resources\" rel=\"noreferrer noopener\" target=\"_blank\">Localizing Package Resources <\/a>.<\/p>\n\n\n\n<p id=\"dcca\"><strong>Products<\/strong>: the output of your package, either a library or an executable produced by a package, and make them visible to other packages.<\/p>\n\n\n\n<p id=\"9438\">Below Pros and Cons of Swift Packages (at least at the time of writing this article).<\/p>\n\n\n\n<p id=\"4bd2\">Pros:<\/p>\n\n\n\n<ol><li>Dependencies managed by Xcode;<\/li><li>Versions managed by Xcode;<\/li><li>No binary compatibility requires, package can be compiled for multiple platforms in the same build operation. There is no need anymore to create separate framework target for each platform;<\/li><li>Distribution in Source form allows inspect the code and step into it while debugging.<\/li><li>Staring Xcode 12 Swift package can contain images, storyboards, XCFrameworks and more other file types.<\/li><li>Cons:<\/li><li>(Only before Xcode 12) Swift packages contain source code but don\u2019t support assets and resources.<\/li><li>(Only before Xcode 12) Swift package can only depend on other Swift packages, binary dependencies aren\u2019t supported.<\/li><li>Distribution in Source form will not fit for framework providers, who don\u2019t want to share source code.<\/li><\/ol>\n\n\n\n<p id=\"6d7a\">When you are making architectural choice between static libraries, frameworks or Swift packages for your iOS application, obviously, you should take into account the limitations of each specific project.<\/p>\n\n\n\n<p id=\"4f14\">Linking too many static libraries into an app produces large app executable files, slow launch times and large memory footprints. Frameworks gives you much more flexibility than static libraries, they can contain resources. But each embedded framework added to project increases startup time as well.<\/p>\n\n\n\n<p id=\"6710\">If you can ship your source files, Swift packages may be the right choice for you. Xcode will take care of all the dependencies, versioning, platforms.<\/p>\n\n\n\n<p>In Swift, packages are <a href=\"https:\/\/developer.apple.com\/documentation\/swift_packages\">reusable components of Swift, Objective-C, Objective-C++, C, or C++ code that developers can use in their projects<\/a>. This is similar to packages in <a href=\"https:\/\/www.npmjs.com\">npm<\/a>.<\/p>\n\n\n\n<p>Packages are primarily distributed through <a href=\"http:\/\/cocoapods.org\">Cocoa Pods<\/a>, <a href=\"https:\/\/www.github.com\/apple\/swift-package-manager\">Swift Package Manager<\/a>, and <a href=\"https:\/\/github.com\/Carthage\/Carthage\">Carthage<\/a>.<\/p>\n\n\n\n<p>Packages can contain Frameworks and Libraries and can use other packages as dependencies.<\/p>\n\n\n\n<p>You would use a package in Swift when you want to re-use a piece of code in different projects as you would an npm package in Javascript projects. An example would be <a href=\"https:\/\/github.com\/RyuGames\/NetworkUtils\">NetworkUtils<\/a> a package distributed on Cocoa Pods that provides networking support.<\/p>\n\n\n\n<p>Packages are just a way to distribute code, like a framework or a library. The benefit comes from how easy it is to manage them. You can manage a list of the dependencies you want to include and the package manager will handle downloading and installing the code into your project for you. It also makes it easier to choose specific versions of packages to use in your project.<\/p>\n\n\n\n<p>For example, if I want to include <code>NetworkUtils<\/code> in my project, I would just edit a <code>Podfile<\/code> (a Cocoa Pods file for managing dependencies) and would just add a line: <code>pod 'NetworkUtils'<\/code> and then run the <code>pod install<\/code> command in terminal and it would load the newest version of the package into my project.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Every developer knows how important to support clean ar [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"_links":{"self":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/5116"}],"collection":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5116"}],"version-history":[{"count":7,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/5116\/revisions"}],"predecessor-version":[{"id":5135,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/5116\/revisions\/5135"}],"wp:attachment":[{"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5116"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}