<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Mattia Campolese on Medium]]></title>
        <description><![CDATA[Stories by Mattia Campolese on Medium]]></description>
        <link>https://medium.com/@matsoftware?source=rss-aa529efed6b3------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*OclhrXcu-_XzZ-o6gNjW3A.jpeg</url>
            <title>Stories by Mattia Campolese on Medium</title>
            <link>https://medium.com/@matsoftware?source=rss-aa529efed6b3------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 08:02:41 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@matsoftware/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[From zero to Heroku with Vapor]]></title>
            <link>https://medium.com/@matsoftware/from-zero-to-heroku-with-vapor-115bedb81560?source=rss-aa529efed6b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/115bedb81560</guid>
            <category><![CDATA[heroku]]></category>
            <category><![CDATA[gitops]]></category>
            <category><![CDATA[server-side-swift]]></category>
            <category><![CDATA[vapor]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Mattia Campolese]]></dc:creator>
            <pubDate>Mon, 13 Apr 2020 10:55:32 GMT</pubDate>
            <atom:updated>2020-04-13T14:10:52.039Z</atom:updated>
            <content:encoded><![CDATA[<p><em>Create, test and deploy your dynamic website with Swift in a few steps.</em></p><p>This is a beginner guide designed for Swift developers who want to create a scalable dynamic website with Continuous Integration of code and in Continuous Delivery.</p><p>At the end of this tutorial, you will be able to deploy your “hello world” website in production in just a few minutes:</p><figure><img alt="MyAwesomeProject deployed on Heroku" src="https://cdn-images-1.medium.com/max/774/1*LckQfJ0ca_3cgSR7jc15lA.png" /></figure><p>The tools that have been chosen are:</p><ul><li><a href="https://vapor.codes/">Vapor</a> 3.x, one of the most elegant web frameworks for Swift</li><li>Git as the version control system and <a href="https://www.github.com">GitHub</a> as the remote storing platform</li><li><a href="https://circleci.com/">CircleCI</a> to set up the Continuous Integration pipeline</li><li><a href="https://www.heroku.com">Heroku</a> as the deployment platform (since vapor.cloud has been <a href="https://docs.vapor.cloud/shutdown/">officially demised</a>)</li></ul><p><em>Note: Heroku provides an all-in-one solution for git repo hosting and CI, but this guide intends to use different tools to not depend on a single provider. Besides, GitHub and CircleCI provide more advanced features and are widely used in the industry.</em></p><h3>Bootstrap a new Vapor project</h3><p>Reference guide:</p><p><a href="https://docs.vapor.codes/3.0/install/macos/">macOS - Vapor Docs</a></p><p>Install Vapor through <a href="https://brew.sh">Homebrew</a>:</p><pre>brew tap vapor/tap<br>brew install vapor/tap/vapor</pre><p>Then bootstrap a new project (e.g. a new website, using the <a href="https://docs.vapor.codes/3.0/getting-started/toolbox/">available templates</a>):</p><pre>vapor new --template=web MyAmazingProject<br>cd MyAmazingProject<br>vapor xcode</pre><p>Test the new website by running the generated Xcode project and navigating to <a href="http://localhost:8080">http://localhost:8080</a>:</p><figure><img alt="Hello world rendition of the Vapor website template" src="https://cdn-images-1.medium.com/max/677/1*EvDaE00GwcB_wkcVRKmPQw.png" /><figcaption><a href="http://localhost:8080.">http://localhost:8080.</a> Time for your first cup of ☕️</figcaption></figure><h3>Push changes on GitHub</h3><p>Create a new empty GitHub repository to host your code, then set it as your default remote for the Vapor project:</p><pre>git remote add origin <a href="mailto:git@github.com">git@github.com</a>:mygithubaccount/my-awesome-project.git</pre><p>Commit and push all your changes:</p><pre>git add . &amp;&amp; git commit -m &quot;MyAwesomeProject bootstrap&quot;<br>git push origin master</pre><h3>Set up the CI pipeline with CircleCI</h3><p>Sign up with your GitHub account on the CircleCI website:</p><p><a href="https://circleci.com/signup/">Sign Up</a></p><p>Then set up a new project by selecting the newly created repo. Ignore the templates offered and click on <em>Start building</em>, then choose to add the configuration manually.</p><p>From the root of your repo, move the generated CircleCI configuration file:</p><pre>mkdir .circleci &amp;&amp; mv config.yml .circleci/config.yml</pre><p>Now you can commit and push the changes. Go back to the CircleCI dashboard and then click on <em>Start Building</em>. After a while, you should get a successful build, and you can also verify the integration of CircleCI on Github:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GlTHSvok5E0zUkUM5KoJNA.png" /><figcaption>Successfully built commit on the MyAmazingProject master branch.</figcaption></figure><h3>Deploy the website with Heroku</h3><p>Everything it’s ready to deploy your website to the public.</p><p>Create a Free Heroku account:</p><p><a href="https://www.heroku.com/pricing">Pricing | Heroku</a></p><p>Then <em>Sign in</em>, <em>Create a new app </em>and choose a region. Then from the app dashboard go to <em>Deploy</em>, <em>Deployment method, </em>select <em>GitHub</em> and connect your account and repository.</p><p>Choose automatic deploys from the <em>master</em> branch and enable the <em>Wait for CI to pass before deploy</em> option.</p><p>Install now the Heroku CLI:</p><pre>brew install heroku/brew/heroku</pre><p>Log in with your email address and install the Vapor buildpack (scripts that are run when the app is deployed):</p><pre>heroku login<br>heroku buildpacks:set vapor/vapor</pre><p>Set the swift version you’re currently using (e.g., using the current stable Xcode 11.4 version):</p><pre>echo “5.2” &gt; .swift-version</pre><p>Then create the <em>Procfile</em> (a file that specifies the commands that are executed by the app on startup):</p><pre>echo &quot;web: Run serve --env production&quot; \<br>  &quot;--hostname 0.0.0.0 --port \$PORT&quot; &gt; Procfile</pre><p>At the time of this writing, you might need also to run:</p><pre>swift package update</pre><p>to update all the dependencies and avoid potential issues with the buildpack scripts.</p><p>Commit all changes and push them to master. A build will start and you can see the deployment progress in the Activity tab of the app dashboard.</p><p>Once the build is successful, you can finally scale the website by running</p><pre>heroku ps:scale web=1</pre><p>Your new app is now finally available at <a href="https://statics-app.herokuapp.com">https://my-amazing-project.herokuapp.com</a>:</p><figure><img alt="MyAwesomeProject deployed on Heroku" src="https://cdn-images-1.medium.com/max/774/1*LckQfJ0ca_3cgSR7jc15lA.png" /><figcaption>Your website has now finally being deployed. Time to celebrate 🍺</figcaption></figure><h4>Point to your custom domain</h4><p>If you’ve purchased a domain for your website, it’s now time to point it to your Heroku application:</p><p><a href="https://devcenter.heroku.com/articles/custom-domains">Custom Domain Names for Apps</a></p><p>After verifying your account you have to execute:</p><pre>heroku domains:add my-amazing-project.com<br>heroku domains</pre><p>to get the DNS Target to use in your hostname provider.</p><h3>Conclusion</h3><p>Setting up a production CI/CD pipeline it’s a fundamental step for accelerated delivery. You can now focus on writing production code that can be automatically tested and deployed in a few minutes by embracing <a href="https://www.gitops.tech/">GitOps</a>:</p><blockquote>GitOps: versioned CI/CD on top of declarative infrastructure. Stop scripting and start shipping. — <a href="https://twitter.com/kelseyhightower/status/953638870888849408">Kelsey Hightower</a></blockquote><p><em>You can find me on </em><a href="https://twitter.com/matsoftware"><em>Twitter</em></a><em> &amp; </em><a href="https://www.linkedin.com/in/matcamp/"><em>LinkedIn</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=115bedb81560" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift code metrics]]></title>
            <link>https://medium.com/@matsoftware/swift-code-metrics-ea9ebf85416f?source=rss-aa529efed6b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/ea9ebf85416f</guid>
            <category><![CDATA[metrics]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[Mattia Campolese]]></dc:creator>
            <pubDate>Sun, 10 Feb 2019 14:56:38 GMT</pubDate>
            <atom:updated>2023-04-01T16:51:24.472Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-nc-sa/4.0/</cc:license>
            <content:encoded><![CDATA[<h4>How to measure the metrics of your Swift project.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*el4GaQp9QxDqYVnLnlzBJg.jpeg" /><figcaption>Dependency graph, deviation from the main sequence and code distribution of different example projects</figcaption></figure><p>In almost every live software product, code evolves with dynamics that are driven by multiple factors, such as product requirements, architectural decisions, developers skills, tools adopted, dependencies, language maturity and others.</p><p>In medium/big size projects, this leads to a growth in complexity that is hard to control without measuring how the codebase is evolving. Assessing the growth of the total LOC (<em>Lines of Code</em>) or the degree of coupling between internal dependencies in a modularized application can give great help in understanding the bigger picture.</p><p>There are several paid and open tools for various languages. For <a href="https://swift.org/">Swift</a>, I’m introducing <a href="https://github.com/matsoftware/swift-code-metrics"><strong>swift code metrics</strong></a>, an open Python package that will analyze your project’s source code directly to inspect for two types of KPIs:</p><h4><strong>Synthetic metrics</strong></h4><p>They measure the absolute number of a specific entity, such as:</p><ul><li>LOC (<em>Lines Of Code</em>)</li><li>NOC (<em>Number Of Comments</em>)</li><li>POC (<em>Percentage Of Comments</em>)</li><li>NOM (<em>Number of Methods</em>)</li><li>Number of concretes (<em>Number of classes and structs</em>)</li><li>NOT (<em>Number Of Tests</em>)</li><li>NOI (<em>Number Of Imports</em>)</li></ul><p>They can help to understand the distribution of the code inside the project (e.g. by assessing the relative size of a module) or to predict the growth of the software over time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/460/1*b1U6Y9CqAIp15Cy42xguiw.jpeg" /><figcaption>Example of a code distribution graph for an app based on LOC</figcaption></figure><h4><strong>Modules coupling</strong></h4><p>For modularized codebases, they measure the degree of coupling between all imported libraries.</p><p>The most important one is probably the <strong>dependencies graph</strong>. It helps to immediately visualize the dependencies between modules (internal or external). The library computes the total number of import calls from each folder identifying a framework (instead of checking the imports from SourceKit) to immediately understand the general level of coupling.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i6dqa3gpS8vcfr4vU51b3Q.jpeg" /><figcaption>Example of an internal dependencies graph: the size of the box is relative to the size of the framework and the number indicates the number of imports of that module from the caller</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eJrdLHNDYkE0SwSfRWBOvg.jpeg" /><figcaption>Complete dependencies graph: external dependencies imports are indicated in orange</figcaption></figure><p>Another important coupling metric is the <strong>distance from the main sequence</strong>, that it’s used to represent the relation between the <em>instability</em> and <em>abstraction</em> of an internal component:</p><p><em>D³ = abs( A + I — 1 )</em></p><p>The instability is defined as below:</p><p><em>I = FanOut / ( FanIn + FanOut)</em></p><p>where:</p><ul><li><em>FanOut</em>: identifies the number of classes inside a component that depends on classes outside the component (outgoing dependencies)</li><li><em>FanIn</em>: identifies the number of classes outside this component that depend on classes within the component (incoming dependencies)</li></ul><p>With I = 1, the component has no dependents and thus unstable and “irresponsible”, making it very easy to change. With I = 0, the situation is the opposite since it doesn’t depend on other components and it has dependents, making it very hard to change.</p><p>The abstraction is obtained by:</p><p><em>A = Na / Nc</em></p><p>where:</p><ul><li><em>Na</em>: number of abstract classes and interfaces in the component</li><li><em>Nc</em>: number of classes in the component</li></ul><p>Not all components should be stable because the system would be hard to change. In general, a component considered stable should be abstract so that it can be easily changed. At the same time, an unstable component should be concrete because its instability allows the implementation inside it to be easy to change.</p><p>In an I/A plot, it’s possible to represent the distribution of the components relative to the distance from the optimum ( D = 0 ) and therefore visually determine two areas that should be ideally avoided by a module:</p><ul><li><em>zone of usefulness</em>: components very abstract with few dependents (mostly useless)</li><li><em>zone of pain</em>: components that are very ‘concrete’ with a lot of dependents, very rigid and hard to change (e.g. usually foundation libraries)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hz7BGk0KO_phKkcbgi0jVQ.jpeg" /><figcaption>Example of the deviation from the main sequence graph</figcaption></figure><h4>Additional metrics</h4><p>In a versioned project (e.g. in a git repository) it can also be possible to compute metrics around code changes over time, such as the git churn rate of certain modules and classes or the overall number of commits/merges. There are already several tools available for <a href="https://en.wikipedia.org/wiki/Version_control">scm</a> (some of them provided directly from the host) that are outside the scope of this article.</p><h4>Get involved</h4><p>Swift Code Metrics is an open source Python tool available on GitHub (<a href="https://github.com/matsoftware/swift-code-metrics">https://github.com/matsoftware/swift-code-metrics</a>).</p><p>Please read the <a href="https://github.com/matsoftware/swift-code-metrics/blob/master/docs/GUIDE.md">documentation</a> and get involved in improving and extending it with your contribution by raising an issue or opening a pull request.</p><p>For a more detailed explanation of the distance from the main sequence and on components coupling please read “<em>Clean Architecture: A Craftsman’s Guide to Software Structure and Design (Robert C. Martin Series)</em>”.</p><figure><a href="https://usejournal.com/?utm_source=medium.com&amp;utm_medium=noteworthy_blog&amp;utm_campaign=guest_post_image"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f2IVAl0TbsfES9cFGYr40g.png" /></a></figure><p>📝 Read this story later in <a href="https://usejournal.com/?utm_source=medium.com&amp;utm_medium=noteworthy_blog&amp;utm_campaign=guest_post_read_later_text">Journal</a>.</p><p>🗞 Wake up every Sunday morning to the week’s most noteworthy Tech stories, opinions, and news waiting in your inbox: <a href="https://usejournal.com/newsletter/?utm_source=medium.com&amp;utm_medium=noteworthy_blog&amp;utm_campaign=guest_post_text">Get the noteworthy newsletter &gt;</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ea9ebf85416f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Enumerable localizable keys in Swift 4.2]]></title>
            <link>https://medium.com/@matsoftware/enumerable-localizable-keys-in-swift-4-2-23c7efd0604b?source=rss-aa529efed6b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/23c7efd0604b</guid>
            <category><![CDATA[localization]]></category>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Mattia Campolese]]></dc:creator>
            <pubDate>Mon, 30 Apr 2018 20:15:04 GMT</pubDate>
            <atom:updated>2018-05-02T06:49:05.086Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PWkPd-kDjttaRnwf9njJmA.png" /><figcaption>A type-safe approach to localization using CaseIterable enums</figcaption></figure><p>Localizing content in iOS apps seems a rather easy process at first. The NSLocalizedString<em> </em>API looks for the translated value of a given key in a plain text Localizable.string file if multiple languages are supported.</p><p>However, this mechanism can easily induce the developer to an error. When the project evolves, the complexity increases: new locales to support, hundreds of new keys, or a different and more complex build process that changes the structure of bundle resources might cause regressions in the app due to missing translations or worse, missing copies.</p><p>Ideally, the developer should use only keys that have their value translated in all supported locales and he should be safe that eventual corruptions of the localization mechanism (missing resources, formatting errors, erroneous key deletions, etc) should be caught at compile-time or by unit tests.</p><p>The main culprit is the manipulation of raw Strings in NSLocalizedString keys and in the Localizable.string file. The usage of plain raw Strings, in fact, defies the advantage of a compile time type safety check.</p><p>One solution to this problem is to implement an opaque type to represent a localizable String that internally makes use of a String enum that contains all the supported keys:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/31a4a4e81d4c4a95f8643cc0dcbd7459/href">https://medium.com/media/31a4a4e81d4c4a95f8643cc0dcbd7459/href</a></iframe><p>This will solve one half of the problem, but how is it possible to guarantee that the Localizable file is not corrupted or that a valid string is provided in all locales?</p><h4>CaseIterable enums to the rescue</h4><p>The <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0194-derived-collection-of-enum-cases.md">CaseIterable</a> protocol conformance in enum introduced in Swift 4.2 makes possible to enumerate through all the defined cases in an enum without implementing the array of all keys manually ( no more var allKeys: [EnumType] = [.case2, .case2, …]<em> </em>!🎊).</p><p>By conforming LocaleKey to CaseIterable then it will be possible to write a simple but effective unit test that will iterate through each case to check if LocalizedText is providing a translated value instead of returning the key itself:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/919766cefa53a4de5b22a60d2f0727d2/href">https://medium.com/media/919766cefa53a4de5b22a60d2f0727d2/href</a></iframe><p>This will flag missing translations and prevent accidental mistakes to be merged in the development branch.</p><h4>Multiple locales</h4><p>The LocalizedText struct can be extended to support the injection of specific tableNames in order to check that a translation is provided for each locale:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b3894ae06ca18adb8dbf7d717a5309ad/href">https://medium.com/media/b3894ae06ca18adb8dbf7d717a5309ad/href</a></iframe><p>The LocaleKeyTests unit test can then check if all supported locales are configured properly:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4c83fc62e760780f4828b711259536ec/href">https://medium.com/media/4c83fc62e760780f4828b711259536ec/href</a></iframe><p>A more extensive example that makes use of a <em>LanguageTableProvider</em> is included in the sample project available on GitHub: <a href="https://github.com/matsoftware/LocaleEnumerable">https://github.com/matsoftware/LocaleEnumerable</a></p><h4>Conclusion</h4><p>The implementation of CaseIterable enum protocol conformance it’s an important step in the evolution of a truly type-safe language. String’s localization is just one of the most simple scenario where its application will help in reducing the impact of human error and therefore time and frustration with a simple unit test in continuous integration.</p><p>Please follow me on LinkedIn: <a href="https://www.linkedin.com/in/matcamp/">https://www.linkedin.com/in/matcamp/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=23c7efd0604b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Circular references in Swift / Objective-C bridging]]></title>
            <link>https://medium.com/@matsoftware/circular-references-in-swift-objective-c-bridging-9bea7afd1253?source=rss-aa529efed6b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/9bea7afd1253</guid>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[macos]]></category>
            <category><![CDATA[objective-c]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Mattia Campolese]]></dc:creator>
            <pubDate>Tue, 29 Aug 2017 14:40:32 GMT</pubDate>
            <atom:updated>2017-08-29T14:40:32.415Z</atom:updated>
            <content:encoded><![CDATA[<p>Any iOS/MacOS project with more than two years of history has to deal with the Swift and Objective-C <a href="https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html"><em>mix and match</em></a>, where different languages try to coexist in a peaceful ecosystem.</p><p>This peace may however be threatened by some special conditions where the bridge between the two languages cannot be built correctly due to ambiguity, like in the case of <em>circular references</em>.</p><p>Take for instance this scenario:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/792/1*EwPUHvHdVF_6l_vqZR9sJQ.png" /><figcaption>Mix and match ambiguity example</figcaption></figure><ol><li>The <em>ObjcMainClass </em>is composed by an object that conforms to the <em>ComponentProtocol</em> written in Swift, therefore it needs to import the <em>ProjectName-Swift.h</em> generated file</li><li>The <em>ObjcMainClassTests</em> is the Objective-C unit test class that will test the <em>ObjcMainClass</em> component. It will make use of a <em>StubComponent</em> object that will conform to <em>ComponentProtocol</em> in order to control the execution flow of the public methods to test.</li><li><em>StubComponent</em> is defined in the unit test target, and it will need to include the <em>@testable import ProjectName</em> code in order to find the protocol definition.</li><li>Since <em>StubComponent</em> lives in the unit target and it’s written in Swift, the <em>ObjcMainClassTests</em> has to import the <em>ProjectNameTests-Swift.h</em> generated file.</li></ol><p>Try to run unit tests and what you get is the <em>“Module ProjectName not found in ProjectNameTests-Swift.h”</em> error:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/932/1*yf_XHqlQe6S70p2RQwQycg.png" /><figcaption>Module ‘ProjectName’ not found in Swift generated file error</figcaption></figure><p>This scenario might be quite common in projects that embrace a <a href="https://agilewarrior.wordpress.com/2015/04/18/classical-vs-mockist-testing/">mockist</a> unit testing approach where concrete stubs for new Swift interfaces are passed to existing Objective-C entities.</p><p>The best solution is to reduce the number of bridges needed between your Objective-C and Swift code. Try to migrate the module or your object graph to Swift, or temporarily write the protocol and stubs in Objective-C before planning the migration itself.</p><p>This second approach is showed in the demo project available on Github, where you can find both failing and passing scenarios described here: <a href="https://github.com/matsoftware/TestObjcSwiftCircularReference">https://github.com/matsoftware/TestObjcSwiftCircularReference</a> .</p><p>Happy bridging☺</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9bea7afd1253" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>