<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hanh Q. Vu</title>
    <description>The latest articles on DEV Community by Hanh Q. Vu (@hanhqvu).</description>
    <link>https://dev.to/hanhqvu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2092628%2F688286ce-7ddf-4f01-a0a0-00198d736523.jpeg</url>
      <title>DEV Community: Hanh Q. Vu</title>
      <link>https://dev.to/hanhqvu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hanhqvu"/>
    <language>en</language>
    <item>
      <title>Tuist &amp; Revenue Cat, Part 2</title>
      <dc:creator>Hanh Q. Vu</dc:creator>
      <pubDate>Wed, 18 Sep 2024 14:15:39 +0000</pubDate>
      <link>https://dev.to/hanhqvu/tuist-revenue-cat-part-2-3oco</link>
      <guid>https://dev.to/hanhqvu/tuist-revenue-cat-part-2-3oco</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This blog post series is done in conjunction with the Ship-a-thon/Melting-hacks&lt;br&gt;
In part 1, I have already explained the basics surrounding these tools.&lt;br&gt;
For part 2, I will go deeper into how to utilize &amp;amp; integrate these tools into your project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Configurations
&lt;/h2&gt;

&lt;p&gt;If you have read part 1 and followed along with the code, you have probably setup Revenue Cat successfully (hopefully). However, in order to actually use the SDK, you need to setup the public key inside your source code.&lt;/p&gt;

&lt;p&gt;As you are well aware, committing the key directly to your version control backend is highly frowned upon. Similar to other languages, you can setup a xcconfig file to setup value that you don’t want to commit to version control.&lt;/p&gt;

&lt;p&gt;You can simply create a xcconfig file and add a definition like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Base.xcconfig
Naming is entirely up to you, also it is not an actual key if you are wondering

RC_PUBLIC_KEY=rc_test_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How do you inject this value into the actual source code? With Tuist, it’s rather simple. You just need to setup a build configuration that reference the value. You can do it like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// You can name the config freely as well, I usually go with Debug, Staging, Release&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="s"&gt;"PROJECT_BASE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"PROJECT_BASE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;configurations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Debug"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;xcconfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Base.xcconfig"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, whenever you build &amp;amp; run your project, the value will be injected into your source code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development setup
&lt;/h2&gt;

&lt;p&gt;After you have completed the configuration setup, you are pretty much ready to monetize your application. However, you are still reliant on Revenue Cat backend to test your purchase or paywall setup. That’s where the StoreKit config comes in.&lt;/p&gt;

&lt;p&gt;Assuming you have already setup your subscription on App Store Connect, you can easily create a StoreKit config directly from Xcode. It will retrieve and create a StoreKit config without you doing much.&lt;/p&gt;

&lt;p&gt;However, since the file is created with Xcode. It is not actually registered within our project since it is all generated by Tuist. There is some extra work in getting it to work with Tuist.&lt;/p&gt;

&lt;p&gt;Let’s create a build config that will be using our StoreKit file instead of retrieving from the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;debugScheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Scheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Debug"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;shared&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;buildAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;buildAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Artomo"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="nv"&gt;testAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;"Artomo"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="nv"&gt;runAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;runAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;executable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Artomo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;storeKitConfigurationPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Debug.storekit"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can easily test and make changes to your subscription offerings locally without needing to fetch from the servers&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;I hope I had done a good job introducing Tuist &amp;amp; Revenue Cat. Both are wonderful tools on their own but can be use together to make your experience developing iOS app all the more better!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>mobile</category>
      <category>swift</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Tuist &amp; Revenue Cat, Part 1</title>
      <dc:creator>Hanh Q. Vu</dc:creator>
      <pubDate>Wed, 18 Sep 2024 14:07:54 +0000</pubDate>
      <link>https://dev.to/hanhqvu/tuist-revenue-cat-part-1-42b9</link>
      <guid>https://dev.to/hanhqvu/tuist-revenue-cat-part-1-42b9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This blog post series is done in conjunction with the Ship-a-thon/Melting-hacks&lt;br&gt;
Part 1 of 2 will focus on explaining why &amp;amp; how to use Tuist with Revenue Cat.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Tuist
&lt;/h2&gt;

&lt;p&gt;I'm sure most iOS engineer have had the (un)fortunate experience of collaborating on a Xcode project. The reality is that Xcode project files are very brittle and while it is not exactly a propriety file formate, the structure and underlying syntax is a mystery in and of itself.&lt;/p&gt;

&lt;p&gt;If you are coming to iOS from other ecosystems with excellent tooling, especially for managing dependencies &amp;amp; configurations, such as Go or Rust, you will be surprised on how cumbersome the workflow in Xcode is.&lt;/p&gt;

&lt;p&gt;Tuist was created to solve this exactly problem. Not only can you manage your depend  dependencies &amp;amp; configurations directly with Swift, you can save so many hours resolving conflict for the Xcode project files. I will not go in depth on how to setup and use Tuist in this blog but I will include resource below for your references.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Revenue Cat
&lt;/h2&gt;

&lt;p&gt;In the same vein with Tuist simplifying the workflow with Xcode, Revenue Cat helps simplifying the way that you can monetize your app.&lt;/p&gt;

&lt;p&gt;I was (un)fortunate to have been able to experience the Stripe SDK before trying my hands at monetizing an iOS app. To say the experience with Stripe is sublime is selling it short. Whatever you need to create an excellent monetization workflow, Stripe has it all. From excellent documentation, beautiful dashboard or convenience integrations, you won't need for much else with Stripe.&lt;/p&gt;

&lt;p&gt;However, the experience with StoreKit is the exact opposite if I might say. Not only you have to contend with a rather poor documentation, there are a lot of back-ends code that you need to maintain to be able to use StoreKit. This is not practical, especially for smaller teams or indie developers. &lt;/p&gt;

&lt;p&gt;Revenue Cat is the perfect tool to help you solve this exact problem &amp;amp; monetize your app quickly. A lot of works that has gone into building a easy-to-use SDK (which is available not only for Swift but many other languages &amp;amp; frameworks for building mobile apps) along with built-in analytics and intuitive dashboard. If you want to learn more about Revenue Cat, do take a look at their &lt;a href="https://www.revenuecat.com" rel="noopener noreferrer"&gt;homepage here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting them together
&lt;/h2&gt;

&lt;p&gt;Each of these tool by itself is already a tremendous boost to your productivity, combining them together is an even better developer experience. However, as great as they are, the documentation cannot cover all use cases. As such, when trying to using them together, I have a bit of a struggle. Hopefully, I can help make using them a little easier.&lt;/p&gt;

&lt;p&gt;Assuming you have setup Tuist on your machine, you can open the Terminal and navigate to the project folder. Executing the command below will open up a Xcode window so you can modify the project configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tuist edit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the Package.swift file. This is where you can declare your dependencies.&lt;br&gt;
The syntax is the same if you have declare a dependency in other Xcode projects' Package.swift.&lt;br&gt;
Let's go ahead and add the Revenue Cat package to your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"YourAwesomeApp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="c1"&gt;// Add your own dependencies here:&lt;/span&gt;
        &lt;span class="c1"&gt;// .package(url: "https://github.com/Alamofire/Alamofire", from: "5.0.0"),&lt;/span&gt;
        &lt;span class="c1"&gt;// You can read more about dependencies here: https://docs.tuist.io/documentation/tuist/dependencies&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"https://github.com/RevenueCat/purchases-ios-spm.git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upToNextMajor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"5.0.0"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please do refer to the Revenue Cat SDK to make sure that you are getting the latest compatible version with your project. Next up, we will declare the package in our project configuration/manifest file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nv"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"RevenueCat"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"RevenueCatUI"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can choose to import only Revenue Cat or with Revenue Cat UI. For me, I imported both because the Revenue Cat UI package will give you access to templated paywall which is well designed and easy to use.&lt;/p&gt;

&lt;p&gt;With this, you have basically finished setting up Revenue Cat in your Tuist project. This blog post only cover the basics to get you started. For part 2, I will delve deeper into the integration and show you the real power of using them together.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.tuist.io" rel="noopener noreferrer"&gt;Offical Tuist Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://asana.com/inside-asana/scaling-a-mature-ios-codebase-with-tuist" rel="noopener noreferrer"&gt;Scaling a mature iOS codebase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>mobile</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
