<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Swift - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Swift - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 01 Jun 2026 12:13:26 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/swift/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build Secure iOS Apps in Swift: Common Security Pitfalls and How to Fix Them ]]>
                </title>
                <description>
                    <![CDATA[ These days, there are many ways attackers can try to compromise your applications. And thanks to the continued increase in cyberattacks, the demand for secure mobile applications – and by extension, secure coding – has never been higher. So if you’re... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-secure-ios-apps-in-swift-common-security-pitfalls-and-how-to-fix-them/</link>
                <guid isPermaLink="false">68ffdf1761d216440f5bb38a</guid>
                
                    <category>
                        <![CDATA[ Web Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ios app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Mon, 27 Oct 2025 21:07:35 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761599240278/644f6ebb-6092-4ea0-99e3-a568bfb0390c.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>These days, there are many ways attackers can try to compromise your applications. And thanks to the continued increase in cyberattacks, the demand for secure mobile applications – and by extension, secure coding – has never been higher.</p>
<p>So if you’re an iOS developer, you should also learn to prioritize security at every stage of app development.</p>
<p>Swift, Apple’s modern programming language, offers a wealth of tools and frameworks that simplify development while enhancing security, but only when used correctly.</p>
<p>This article explores 10 common security pitfalls in Swift-based iOS apps and offers practical strategies to mitigate them.</p>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<p>Before diving in, you’ll need:</p>
<ul>
<li><p>Working knowledge of Swift and iOS development.</p>
</li>
<li><p>Access to Xcode.</p>
</li>
<li><p>Basic understanding of how iOS apps communicate with servers.</p>
</li>
<li><p>Familiarity with Terminal/command line basics.</p>
</li>
</ul>
<p>The code examples are practical and explained step-by-step, making them accessible to junior developers while still offering value to experienced ones looking to strengthen their app's security.</p>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<dl>
<ul>
<li><a href="" id="heading-what-are-the-most-prevalent-security-traps-in-swift-ios-applications">What are the Most Prevalent Security Traps in Swift iOS Applications?</a>
<ul>
<li><a href="" id="heading-1-insecure-data-storage">1. Insecure Data Storage</a></li>
<li><a href="" id="heading-2-weak-network-communication">2. Weak Network Communication</a></li>
<li><a href="" id="heading-3-improper-input-validation">3. Improper Input Validation</a></li>
<li><a href="" id="heading-4-hardcoding-secrets">4. Hardcoding Secrets</a></li>
<li><a href="" id="heading-5-insufficient-authentication-and-authorization">5. Insufficient Authentication and Authorization</a></li>
<li><a href="" id="heading-6-insecure-logging-and-error-handling">6. Insecure Logging and Error Handling</a></li>
<li><a href="" id="heading-7-ignoring-code-obfuscation-and-reverse-engineering">7. Ignoring Code Obfuscation and Reverse Engineering</a></li>
<li><a href="" id="heading-8-insecure-third-party-libraries">8. Insecure Third-Party Libraries</a></li>
<li><a href="" id="heading-9-insufficient-biometric-and-multi-factor-authentication">9. Insufficient Biometric and Multi-Factor Authentication</a></li>
<li><a href="" id="heading-10-disregarding-periodic-security-testing">10. Disregarding Periodic Security Testing</a></li>
</ul>
</li>
</ul>
</dl>

<h2 id="heading-what-are-the-most-prevalent-security-traps-in-swift-ios-applications"><strong>What are the Most Prevalent Security Traps in Swift iOS Applications?</strong></h2>
<p>Swift and iOS offer robust security features, but mistakes still happen. Following are the most common traps and how to fix them:</p>
<h3 id="heading-1-insecure-data-storage">1. Insecure Data Storage</h3>
<p>Among the most common mistakes developers make is having sensitive data stored insecurely. Passwords, tokens, or even individual user data can be left by accident in UserDefaults or local storage in unencrypted form. </p>
<p>While UserDefaults is convenient for small amounts of data, it is not secure for sensitive data as it is so easily accessible to attackers if the device is compromised.</p>
<h4 id="heading-how-to-fix">How to Fix:</h4>
<p>Use the Keychain Services API to securely store sensitive data. Keychain encrypts data and binds it to the device so that it can't be accessed by other unauthorized applications or users.</p>
<p>You can securely store credentials using libraries in Swift such as KeychainAccess or the built-in SecItemAdd and SecItemCopyMatching functions.</p>
<p>For example, this how you can store a user password in Keychain so as to ensure sensitive data is stored securely:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">do</span> {

<span class="hljs-keyword">try</span> keychain.<span class="hljs-keyword">set</span>(<span class="hljs-string">"userPassword123"</span>, key: <span class="hljs-string">"userPassword"</span>)

} <span class="hljs-keyword">catch</span> {

    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Error saving to Keychain: \(error)"</span>)

}
</code></pre>
<p>Behind the scenes, here’s what happens when you call <code>keychain.set("userPassword123", key: "userPassword")</code> inside a KeychainManager class that uses Apple’s native Security framework for storage:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> Security

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">KeychainManager</span> </span>{
 <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">set</span><span class="hljs-params">(<span class="hljs-number">_</span> value: String, key: String)</span></span> <span class="hljs-keyword">throws</span> {
     <span class="hljs-comment">// 1. Convert string to Data</span>
     <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> data = value.data(using: .utf8) <span class="hljs-keyword">else</span> {
         <span class="hljs-keyword">throw</span> <span class="hljs-type">NSError</span>(domain: <span class="hljs-string">"KeychainManager"</span>, code: -<span class="hljs-number">1</span>)
     }

     <span class="hljs-comment">// 2. Build the query dictionary</span>
     <span class="hljs-keyword">let</span> query: [<span class="hljs-type">String</span>: <span class="hljs-type">Any</span>] = [
         <span class="hljs-comment">// Store as password</span>
         kSecClass <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: kSecClassGenericPassword,
         <span class="hljs-comment">// Your app's bundle identifier</span>
         kSecAttrService <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: <span class="hljs-string">"com.yourapp.keychain"</span>,
         <span class="hljs-comment">// "userPassword"</span>
         kSecAttrAccount <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: key,
         <span class="hljs-comment">// "userPassword123" encrypted</span>
         kSecValueData <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: data,
         kSecAttrAccessible <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: kSecAttrAccessibleAfterFirstUnlock
     ]
     <span class="hljs-comment">// 3. Save to keychain (iOS encrypts it automatically)</span>
     <span class="hljs-keyword">let</span> status = <span class="hljs-type">SecItemAdd</span>(query <span class="hljs-keyword">as</span> <span class="hljs-type">CFDictionary</span>, <span class="hljs-literal">nil</span>)
     <span class="hljs-comment">// 4. Check if successful</span>
     <span class="hljs-keyword">guard</span> status == errSecSuccess <span class="hljs-keyword">else</span> {
         <span class="hljs-keyword">throw</span> <span class="hljs-type">NSError</span>(domain: <span class="hljs-string">"KeychainManager"</span>, code: <span class="hljs-type">Int</span>(status))
     }
 }
}
</code></pre>
<p>When this function runs, iOS converts the string value, such as "userPassword123", into encrypted binary data and stores it securely in the device’s Keychain database. The entry is saved under the provided key (for example, "userPassword"), and only your app can access it.</p>
<p>Behind the scenes, the Keychain leverages strong security features, including hardware-backed encryption using device-specific keys, optional biometric protection through Face ID or Touch ID, and app-level isolation to ensure that no other app can read or modify your stored credentials.</p>
<h3 id="heading-2-weak-network-communication">2. Weak Network Communication</h3>
<p>Transmitting sensitive data over the network is another area prone to vulnerabilities. Using unencrypted HTTP connections exposes your app to man-in-the-middle (MITM) attacks, allowing attackers to intercept and modify data in transit.  </p>
<p><strong>The Problem</strong>: When data travels between your app and server over an insecure connection, attackers on the same network (like public Wi-Fi) can:</p>
<ul>
<li><p>Read sensitive information (passwords, personal data, payment details)</p>
</li>
<li><p>Modify requests and responses</p>
</li>
<li><p>Impersonate your legitimate server</p>
</li>
</ul>
<h4 id="heading-how-to-fix-1">How to Fix:</h4>
<p><strong>1. Always Use HTTPS</strong><br>HTTPS encrypts all data in transit, making it unreadable to attackers. iOS's App Transport Security (ATS) enforces this by blocking insecure HTTP connections by default:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// ❌ INSECURE - HTTP connection (blocked by ATS by default)</span>
<span class="hljs-keyword">let</span> url = <span class="hljs-type">URL</span>(string: <span class="hljs-string">"http://api.example.com/login"</span>)

<span class="hljs-comment">// ✅ SECURE - HTTPS connection</span>
<span class="hljs-keyword">let</span> url = <span class="hljs-type">URL</span>(string: <span class="hljs-string">"https://api.example.com/login"</span>)
</code></pre>
<p>You’ll want to avoid adding ATS exceptions to your Info.plist unless absolutely necessary. If a third-party API only supports HTTP, contact them to upgrade or find a more secure alternative.</p>
<p><strong>2. Implement Certificate Pinning (Advanced Protection)</strong></p>
<p>Even with HTTPS, your app could still be vulnerable to sophisticated MITM attacks. An attacker could install a fraudulent certificate on a user's device (through malware or social engineering), for example, and intercept HTTPS traffic that appears valid. The attacker's fake certificate would be trusted by the device, allowing them to decrypt and read "secure" communications.</p>
<p>Certificate pinning solves this by making your app trust only your specific server's certificate, rejecting all others – even if they're otherwise valid.</p>
<p><strong>How Certificate Pinning Works:</strong></p>
<p>Your app stores the expected certificate (or its public key hash) and validates it during each connection:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SecureNetworkManager</span>: <span class="hljs-title">NSObject</span>, <span class="hljs-title">URLSessionDelegate</span> </span>{

    <span class="hljs-comment">// Store your server's certificate hash</span>
    <span class="hljs-comment">// Get this by running: openssl x509 -in certificate.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">let</span> expectedPublicKeyHash = <span class="hljs-string">"YOUR_CERTIFICATE_HASH_HERE"</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">urlSession</span><span class="hljs-params">(
        <span class="hljs-number">_</span> session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping <span class="hljs-params">(URLSession.AuthChallengeDisposition, URLCredential?)</span></span></span> -&gt; <span class="hljs-type">Void</span>
    ) {
        <span class="hljs-comment">// Step 1: Check if this is a server trust challenge (certificate validation)</span>
        <span class="hljs-keyword">guard</span> challenge.protectionSpace.authenticationMethod == <span class="hljs-type">NSURLAuthenticationMethodServerTrust</span>,
              <span class="hljs-keyword">let</span> serverTrust = challenge.protectionSpace.serverTrust
        <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// Not a certificate challenge; use default handling</span>
            completionHandler(.performDefaultHandling, <span class="hljs-literal">nil</span>)
            <span class="hljs-keyword">return</span>
        }

        <span class="hljs-comment">// Step 2: Validate that the server's certificate matches our pinned certificate</span>
        <span class="hljs-keyword">if</span> isValidServerTrust(serverTrust) {
            <span class="hljs-comment">// Certificate matches - proceed with the connection</span>
            completionHandler(.useCredential, <span class="hljs-type">URLCredential</span>(trust: serverTrust))
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// Certificate doesn't match - reject the connection to prevent MITM attack</span>
            completionHandler(.cancelAuthenticationChallenge, <span class="hljs-literal">nil</span>)
        }
    }

    <span class="hljs-comment">// Validates the server's certificate against our pinned hash</span>
    <span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">isValidServerTrust</span><span class="hljs-params">(<span class="hljs-number">_</span> serverTrust: SecTrust)</span></span> -&gt; <span class="hljs-type">Bool</span> {
        <span class="hljs-comment">// Extract the server's certificate</span>
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> serverCertificate = <span class="hljs-type">SecTrustGetCertificateAtIndex</span>(serverTrust, <span class="hljs-number">0</span>) <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
        }

        <span class="hljs-comment">// Get the public key from the certificate</span>
        <span class="hljs-keyword">let</span> serverPublicKey = <span class="hljs-type">SecCertificateCopyKey</span>(serverCertificate)
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> publicKey = serverPublicKey <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
        }

        <span class="hljs-comment">// Convert the public key to data and hash it</span>
        <span class="hljs-keyword">var</span> error: <span class="hljs-type">Unmanaged</span>&lt;<span class="hljs-type">CFError</span>&gt;?
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> publicKeyData = <span class="hljs-type">SecKeyCopyExternalRepresentation</span>(publicKey, &amp;error) <span class="hljs-keyword">as</span> <span class="hljs-type">Data?</span> <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
        }

        <span class="hljs-comment">// Hash the public key using SHA-256</span>
        <span class="hljs-keyword">let</span> publicKeyHash = <span class="hljs-type">SHA256</span>.hash(data: publicKeyData)
        <span class="hljs-keyword">let</span> publicKeyHashString = <span class="hljs-type">Data</span>(publicKeyHash).base64EncodedString()

        <span class="hljs-comment">// Compare with our expected hash</span>
        <span class="hljs-keyword">return</span> publicKeyHashString == expectedPublicKeyHash
    }
}
</code></pre>
<p>What this code does, step-by-step:</p>
<ol>
<li><p><code>urlSession(_:didReceive:completionHandler:)</code> – This method is called whenever your app makes an HTTPS connection. iOS asks: "Should I trust this server's certificate?"</p>
</li>
<li><p>Check authentication method – We verify this is a server trust challenge (certificate validation), not some other type of authentication.</p>
</li>
<li><p>Validate the certificate – We call <code>isValidServerTrust()</code>, which:</p>
<ul>
<li><p>Extracts the server's certificate from the connection</p>
</li>
<li><p>Gets the public key from that certificate</p>
</li>
<li><p>Hashes the public key using SHA-256</p>
</li>
<li><p>Compares the hash to our stored, expected hash</p>
</li>
</ul>
</li>
</ol>
<ol start="4">
<li>Make a decision:</li>
</ol>
<ul>
<li><p>If hashes match, then the server is legitimate. Proceed with <code>.useCredential</code>.</p>
</li>
<li><p>If hashes don't match, we have a potential MITM attack. Cancel with <code>.cancelAuthenticationChallenge</code>.</p>
</li>
</ul>
<p>So how does this prevent MITM attacks? Even if an attacker installs a fraudulent certificate on the user's device and intercepts traffic, their certificate's hash won't match your pinned hash. Your app will reject the connection, preventing the attacker from decrypting your traffic.</p>
<p><strong>3. Additional Protection: Recommend a VPN on Public Wi-Fi</strong></p>
<p>You can also recommend that users connect through a VPN when on public Wi-Fi for an added layer of security, and provide guidance on <a target="_blank" href="https://surfshark.com/blog/how-to-use-a-vpn">how to use a VPN</a> effectively to keep their data safe.</p>
<p>For developers, maintaining strong app security also depends on having a well-optimized system, learning <a target="_blank" href="https://cleanmymac.com/blog/macos-tahoe-slow">how to speed up a slow Mac</a> can help ensure smoother builds, faster testing, and a more secure overall development workflow.</p>
<h3 id="heading-3-improper-input-validation">3. Improper Input Validation</h3>
<p>Some developers neglect correct input validation, leading to a number of vulnerabilities including SQL injection, remote code execution, and data corruption.</p>
<p>While Swift has strong typing support, some developers don’t sanitize user input or API responses. Incorporating real-time <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-email-validation-api-for-flask-user-authentication/">API email validation</a> ensures that users provide legitimate, properly formatted email addresses before they are stored or processed, reducing both security risks and data quality issues.</p>
<h4 id="heading-how-to-fix-2">How to Fix:</h4>
<p>Input validation is your first line of defense against malicious data. Here's how to protect your iOS applications:</p>
<p><strong>1. Validate User Input with Patterns</strong></p>
<p>Always validate user input using regular expressions or predefined patterns before processing. For example, when accepting email addresses:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">isValidEmail</span><span class="hljs-params">(<span class="hljs-number">_</span> email: String)</span></span> -&gt; <span class="hljs-type">Bool</span> {
    <span class="hljs-keyword">let</span> emailRegex = <span class="hljs-string">"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"</span>
    <span class="hljs-keyword">let</span> emailPredicate = <span class="hljs-type">NSPredicate</span>(format: <span class="hljs-string">"SELF MATCHES %@"</span>, emailRegex)
    <span class="hljs-keyword">return</span> emailPredicate.evaluate(with: email)
}

<span class="hljs-comment">// Only accept properly formatted data</span>
<span class="hljs-keyword">guard</span> isValidEmail(userEmail) <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Reject invalid input</span>
    <span class="hljs-keyword">return</span>
}
</code></pre>
<p>This ensures that only properly formatted data is accepted, preventing malformed or malicious input from entering your system.</p>
<p><strong>2. Sanitize API Responses</strong></p>
<p>Never trust external data. Always validate and sanitize API responses before using them:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> userAge = apiResponse[<span class="hljs-string">"age"</span>] <span class="hljs-keyword">as</span>? <span class="hljs-type">Int</span>,
   userAge &gt;= <span class="hljs-number">0</span> &amp;&amp; userAge &lt;= <span class="hljs-number">150</span> {
    <span class="hljs-comment">// Safe to use</span>
    user.age = userAge
} <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Handle invalid data appropriately</span>
    <span class="hljs-keyword">throw</span> <span class="hljs-type">ValidationError</span>.invalidAge
}
</code></pre>
<p><strong>3. Use Parameterized Queries (Most Critical)</strong></p>
<p>The most dangerous mistake is building database queries through string concatenation. Consider this vulnerable code:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// ❌ NEVER DO THIS - Vulnerable to SQL Injection</span>
<span class="hljs-keyword">let</span> username = userInput  <span class="hljs-comment">// Could be: "admin' OR '1'='1"</span>
<span class="hljs-keyword">let</span> query = <span class="hljs-string">"SELECT * FROM users WHERE username = '\(username)'"</span>
database.execute(query)
</code></pre>
<p>If a malicious user enters admin' OR '1'='1 as their username, the query becomes:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> <span class="hljs-keyword">users</span> <span class="hljs-keyword">WHERE</span> username = <span class="hljs-string">'admin'</span> <span class="hljs-keyword">OR</span> <span class="hljs-string">'1'</span>=<span class="hljs-string">'1'</span>
</code></pre>
<p>This would return all users in the database instead of just one, potentially exposing sensitive data. The secure solution uses parameterized queries:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// ✅ SAFE - Using parameterized queries</span>
<span class="hljs-keyword">let</span> query = <span class="hljs-string">"SELECT * FROM users WHERE username = ?"</span>
database.execute(query, withArgumentsIn: [username])
</code></pre>
<p>In this approach, the <code>?</code> is a placeholder that the database treats as a parameter, not as part of the SQL command. The username value is passed separately in the <code>withArgumentsIn</code> array.</p>
<p>This means that even if a user tries to inject SQL code like <code>admin' OR '1'='1</code>, the database will treat the entire string as a literal username to search for – not as executable SQL code. The database engine automatically escapes any special characters, completely eliminating the risk of SQL injection.</p>
<p>By separating the query structure from the data, parameterized queries ensure that user input can never alter the intended logic of your SQL statements.</p>
<h3 id="heading-4-hardcoding-secrets">4. Hardcoding Secrets</h3>
<p>API keys, credentials, or private tokens hard-coded in the source code is another serious security mistake. Attackers can extract such secrets from compiled binaries using reverse-engineering tools, especially for apps released to the public.</p>
<p>Once exposed, these credentials can be used to access your backend services, potentially leading to data breaches or unauthorized charges.</p>
<h4 id="heading-the-problem-hardcoded-secrets">The Problem – Hardcoded Secrets:</h4>
<pre><code class="lang-swift"><span class="hljs-comment">// NEVER DO THIS</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">APIClient</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">let</span> apiKey = <span class="hljs-string">"1234567890abcdef"</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">let</span> secretToken = <span class="hljs-string">"sk_live_51H..."</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">makeRequest</span><span class="hljs-params">()</span></span> {
        <span class="hljs-comment">// These secrets are embedded in your binary</span>
        <span class="hljs-keyword">let</span> headers = [<span class="hljs-string">"Authorization"</span>: <span class="hljs-string">"Bearer \(apiKey)"</span>]
    }
}
</code></pre>
<p><strong>How to Fix:</strong></p>
<p>Never store sensitive credentials directly in your code. Here are secure alternatives:</p>
<p><strong>Solution 1: Fetch Secrets from Backend at Runtime</strong></p>
<p>The most secure approach is to never store secrets on the client at all. Instead, authenticate users and let your backend make authorized API calls:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">APIClient</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> sessionToken: <span class="hljs-type">String?</span>

    <span class="hljs-comment">// User logs in and receives a temporary session token</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">authenticateUser</span><span class="hljs-params">(email: String, password: String)</span></span> async <span class="hljs-keyword">throws</span> {
        <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">try</span> await backend.login(email: email, password: password)
        <span class="hljs-comment">// Store only a temporary, user-specific session token</span>
        <span class="hljs-keyword">self</span>.sessionToken = response.sessionToken
    }

    <span class="hljs-comment">// Backend handles the actual API calls with the real API key</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">fetchUserData</span><span class="hljs-params">()</span></span> async <span class="hljs-keyword">throws</span> -&gt; <span class="hljs-type">UserData</span> {
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> token = sessionToken <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">throw</span> <span class="hljs-type">AuthError</span>.notAuthenticated
        }

        <span class="hljs-comment">// Your backend receives this request, validates the session token,</span>
        <span class="hljs-comment">// then uses its own API keys to fetch data from third-party services</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">try</span> await backend.getUserData(sessionToken: token)
    }
}
</code></pre>
<p><strong>How this works:</strong></p>
<p>Your app never knows the actual API keys. When a user needs data, your app sends a request to your own backend server with a session token. Your backend validates the token, then uses its own securely stored API keys to make the actual third-party API calls. This way, the real secrets never leave your server.</p>
<p><strong>Solution 2: Environment Variables or Config Files (Development Only)</strong></p>
<p>For development environments, use .xcconfig files that are excluded from version control:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// Secrets.xcconfig (add to .gitignore!)</span>
<span class="hljs-type">API_KEY</span> = your_dev_api_key_here
<span class="hljs-type">API_SECRET</span> = your_dev_secret_here

<span class="hljs-comment">// Access in your code through Info.plist</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Config</span> </span>{
    <span class="hljs-keyword">static</span> <span class="hljs-keyword">let</span> apiKey: <span class="hljs-type">String</span> = {
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> key = <span class="hljs-type">Bundle</span>.main.object(forInfoDictionaryKey: <span class="hljs-string">"API_KEY"</span>) <span class="hljs-keyword">as</span>? <span class="hljs-type">String</span> <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">fatalError</span>(<span class="hljs-string">"API_KEY not found in configuration"</span>)
        }
        <span class="hljs-keyword">return</span> key
    }()
}
</code></pre>
<p><strong>Important</strong>: This approach is only suitable for non-production environments! Never ship production API keys with your app, even in config files.</p>
<h3 id="heading-5-insufficient-authentication-and-authorization">5. Insufficient Authentication and Authorization</h3>
<p>Relying on client-side authentication and authorization checks is risky. Attackers can cause the app to bypass these checks and access in an unauthorized way by brute forcing or tampering with the app/runtime.</p>
<h4 id="heading-how-to-fix-3">How to Fix:</h4>
<ul>
<li><p>Do authentication and authorization on the server side instead of the client-side.</p>
</li>
<li><p>Use JWT (JSON Web Tokens) or OAuth 2.0 for authenticated user login.</p>
</li>
<li><p>Token expiration and refresh logic needs to be implemented in order to minimize the likelihood of token theft.</p>
</li>
</ul>
<p><strong>Example: Securely sending JWT:</strong></p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> request = <span class="hljs-type">URLRequest</span>(url: apiURL)

request.setValue(<span class="hljs-string">"Bearer \(jwtToken)"</span>, forHTTPHeaderField: <span class="hljs-string">"Authorization"</span>)
</code></pre>
<h3 id="heading-6-insecure-logging-and-error-handling">6. Insecure Logging and Error Handling</h3>
<p>Extensive and insecure logging practices, as well as uncaught exceptions, can lead to the exposure of sensitive information including usernames, passwords, and API keys.</p>
<h4 id="heading-how-to-fix-4">How to Fix:</h4>
<ul>
<li><p>Log sensitive information carefully.</p>
</li>
<li><p>Implement controlled error management and provide the minimum amount of information in user-presented messages.</p>
</li>
<li><p>Implement secure logging libraries that mask or encrypt personal data.</p>
</li>
</ul>
<pre><code class="lang-swift"><span class="hljs-keyword">do</span> {
    <span class="hljs-keyword">try</span> someRiskyOperation()
} <span class="hljs-keyword">catch</span> {
    <span class="hljs-comment">// Log error securely</span>
    <span class="hljs-type">Logger</span>.log(<span class="hljs-string">"Operation failed: \(error.localizedDescription)"</span>)
}
</code></pre>
<h3 id="heading-7-ignoring-code-obfuscation-and-reverse-engineering">7. Ignoring Code Obfuscation and Reverse Engineering</h3>
<p>Swift binaries can be reverse-engineered to expose sensitive business logic, algorithms, or hidden secrets. Attackers use tools like Hopper Disassembler, class-dump, or IDA Pro to decompile your app and analyze how it works internally. This risk is often underestimated, especially for smaller apps, but any app can be a target.</p>
<p>This means that when you compile a Swift app, the resulting binary contains:</p>
<ul>
<li><p>Class names and method signatures</p>
</li>
<li><p>String literals (URLs, error messages, keys)</p>
</li>
<li><p>The structure of your code logic</p>
</li>
<li><p>Algorithm implementations</p>
</li>
</ul>
<p>An attacker can extract this information and use it to understand your app's authentication flow and bypass it, copy your proprietary algorithms, find hardcoded API endpoints or keys you thought were "hidden", discover premium features to unlock without paying, and so on.</p>
<p><strong>Why It's Bad – Real Example:</strong></p>
<p>Let's imagine you have a premium feature check in your app:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FeatureManager</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">isPremiumUser</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">Bool</span> {
        <span class="hljs-comment">// Check if user has premium access</span>
        <span class="hljs-keyword">let</span> hasSubscription = <span class="hljs-type">UserDefaults</span>.standard.bool(forKey: <span class="hljs-string">"premium_unlocked"</span>)
        <span class="hljs-keyword">return</span> hasSubscription
    }

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">unlockPremiumFeature</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">guard</span> isPremiumUser() <span class="hljs-keyword">else</span> {
            showPaywall()
            <span class="hljs-keyword">return</span>
        }
        <span class="hljs-comment">// Show premium content</span>
        showPremiumContent()
    }
}
</code></pre>
<p>An attacker could reverse-engineer your app and discover that the method <code>isPremiumUser()</code> controls access, and that it simply checks a <code>UserDefaults</code> key called <code>premium_unlocked</code>. They would then know that they could use runtime manipulation tools to set this value to true, bypassing your paywall entirely.</p>
<p><strong>How to Fix:</strong></p>
<p><strong>1. Use Swift Compiler Optimizations</strong></p>
<p>Enable optimization flags that strip debugging symbols and make the binary harder to read:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// In your build settings:</span>
<span class="hljs-comment">// - Set "Optimization Level" to "-O" (or -Osize) for release builds</span>
<span class="hljs-comment">// - Enable "Strip Debug Symbols During Copy" = YES</span>
<span class="hljs-comment">// - Set "Strip Style" to "All Symbols"</span>
</code></pre>
<p>This removes function names and makes the compiled code less readable – though class/method names remain partially visible.</p>
<p><strong>2. Use Symbol Obfuscation Tools</strong></p>
<p>Tools like SwiftShield can rename your classes, methods, and properties to meaningless names:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// Before obfuscation (readable to attackers):</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FeatureManager</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">isPremiumUser</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">Bool</span> { ... }
}

<span class="hljs-comment">// After obfuscation (harder to understand):</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">a7f3b2</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">x9k2m</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">Bool</span> { ... }
}
</code></pre>
<p>While this doesn't prevent reverse engineering, it makes it significantly harder for attackers to understand what the code does.</p>
<p><strong>3. Move Sensitive Logic to the Server (Best Practice)</strong></p>
<p>Instead of checking premium status locally, verify it server-side:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// ✅ Secure approach - Server validates everything</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FeatureManager</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">unlockPremiumFeature</span><span class="hljs-params">()</span></span> async {
        <span class="hljs-keyword">do</span> {
            <span class="hljs-comment">// Server checks if user truly has premium access</span>
            <span class="hljs-keyword">let</span> hasAccess = <span class="hljs-keyword">try</span> await backend.verifyPremiumAccess(userId: currentUserId)

            <span class="hljs-keyword">if</span> hasAccess {
                showPremiumContent()
            } <span class="hljs-keyword">else</span> {
                showPaywall()
            }
        } <span class="hljs-keyword">catch</span> {
            <span class="hljs-comment">// Handle error</span>
            showPaywall()
        }
    }
}
</code></pre>
<p><strong>How this works:</strong></p>
<p>Your backend maintains the source of truth about premium access. Even if an attacker reverse-engineers your app and tries to bypass the check, the server will reject unauthorized requests. The app becomes just a UI layer, while all critical decisions happen server-side – where attackers can't manipulate them.</p>
<p>The key principle is to assume your app code is public: never rely on client-side checks for security-critical operations like payments, access control, or authentication. Use obfuscation to make reverse engineering harder, but ultimately move sensitive logic to your secure backend</p>
<h3 id="heading-8-insecure-third-party-libraries">8. Insecure Third-Party Libraries</h3>
<p>Third-party libraries are at risk if they are hacked or outdated. Developers might inadvertently prioritize app functionality over potential security risks from dependencies, and <a target="_blank" href="https://airbyte.com/top-etl-tools-for-sources/etl-tools">ETL tools</a> can further help by streamlining the monitoring and processing of dependency-related data to identify vulnerabilities more efficiently.</p>
<p>On a broader scale, implementing strong data center security practices ensures that even if third-party components introduce risks, the underlying infrastructure remains resilient against attacks.</p>
<h4 id="heading-how-to-fix-5">How to Fix:</h4>
<ul>
<li><p>Use only high-quality, well-maintained libraries.</p>
</li>
<li><p>Update dependencies and monitor CVEs (Common Vulnerabilities and Exposures).</p>
</li>
<li><p>Audit library code if it handles sensitive data.</p>
</li>
</ul>
<h3 id="heading-9-insufficient-biometric-and-multi-factor-authentication">9. Insufficient Biometric and Multi-Factor Authentication</h3>
<p>Most applications rely on passwords alone, which are vulnerable to being hacked. Enabling biometrics like Face ID or Touch ID enhances security for users.</p>
<h4 id="heading-how-to-fix-6">How to Fix:</h4>
<ul>
<li><p>Tie LocalAuthentication framework for biometric authentication.</p>
</li>
<li><p>Combine biometrics with server-based authentication for multifactor authentication (MFA).</p>
</li>
</ul>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> LocalAuthentication

<span class="hljs-keyword">let</span> context = <span class="hljs-type">LAContext</span>()

<span class="hljs-keyword">var</span> error: <span class="hljs-type">NSError?</span>

<span class="hljs-keyword">if</span> context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &amp;error) {

    context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,

                        localizedReason: <span class="hljs-string">"Access your account"</span>) { success, authError <span class="hljs-keyword">in</span>

        <span class="hljs-type">DispatchQueue</span>.main.async {

         <span class="hljs-keyword">if</span> success {

                <span class="hljs-comment">// Proceed securely</span>

         } <span class="hljs-keyword">else</span> {

                <span class="hljs-comment">// Handle failure (authError may contain the reason)</span>

                <span class="hljs-built_in">print</span>(<span class="hljs-string">"Authentication failed: \(authError?.localizedDescription ?? "</span><span class="hljs-type">Unknown</span> error<span class="hljs-string">")"</span>)

         }

     }

}

} <span class="hljs-keyword">else</span> {

<span class="hljs-comment">// Biometrics not available, check error for details</span>

    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Biometrics unavailable: \(error?.localizedDescription ?? "</span><span class="hljs-type">Unknown</span> error<span class="hljs-string">")"</span>)

}
</code></pre>
<h3 id="heading-10-disregarding-periodic-security-testing">10. Disregarding Periodic Security Testing</h3>
<p>Apps, despite following best practices during development, often contain unexplored vulnerabilities that emerge from complex interactions, third-party dependencies, or newly discovered attack vectors. Regular security testing is absolutely essential to discover these vulnerabilities before attackers exploit them.</p>
<p>Security testing should happen at multiple stages, using accessible tools and practices:</p>
<ol>
<li><p><strong>Automated security scans:</strong> Run automatically with every build to catch common issues.</p>
</li>
<li><p><strong>Self-conducted code audits:</strong> Regular security-focused reviews of your own code using established guidelines.</p>
</li>
<li><p><strong>Vulnerability scanning tools:</strong> Use free tools like MobSF to analyze your app for security flaws.</p>
</li>
<li><p><strong>Dependency audits:</strong> Checking third-party libraries for known security vulnerabilities.</p>
</li>
</ol>
<p><strong>How to Fix:</strong></p>
<p><strong>1. Implement Automated Security Scans in CI/CD</strong></p>
<p>Integrate security scanning tools into your continuous integration pipeline so every code change is automatically checked:</p>
<pre><code class="lang-swift"># <span class="hljs-type">Example</span>: <span class="hljs-type">GitHub</span> <span class="hljs-type">Actions</span> workflow <span class="hljs-keyword">for</span> automated security scanning
name: <span class="hljs-type">Security</span> <span class="hljs-type">Scan</span>

on: [push, pull_request]

jobs:
  security-scan:
    runs-on: macos-latest

    steps:
      - name: <span class="hljs-type">Checkout</span> code
        uses: actions/checkout@v3

      - name: <span class="hljs-type">Run</span> <span class="hljs-type">MobSF</span> <span class="hljs-type">Security</span> <span class="hljs-type">Scan</span>
        run: |
          # <span class="hljs-type">Mobile</span> <span class="hljs-type">Security</span> <span class="hljs-type">Framework</span> - scans <span class="hljs-keyword">for</span> common vulnerabilities
          docker run -v $(pwd):/app opensecurity/mobile-security-framework-mobsf

      - name: <span class="hljs-type">Dependency</span> <span class="hljs-type">Vulnerability</span> <span class="hljs-type">Check</span>
        run: |
          # <span class="hljs-type">Check</span> <span class="hljs-type">CocoaPods</span>/<span class="hljs-type">SPM</span> dependencies <span class="hljs-keyword">for</span> known <span class="hljs-type">CVEs</span>
          brew install dependency-check
          dependency-check --scan ./<span class="hljs-type">Podfile</span>.lock --format <span class="hljs-type">JSON</span>

      - name: <span class="hljs-type">Secret</span> <span class="hljs-type">Detection</span>
        run: |
          # <span class="hljs-type">Detect</span> accidentally committed secrets
          brew install truffleHog
          truffleHog filesystem . --json

      - name: <span class="hljs-type">Fail</span> build on critical issues
        run: |
          <span class="hljs-keyword">if</span> grep -q <span class="hljs-string">"CRITICAL"</span> security-report.json; then
            echo <span class="hljs-string">"Critical security issues found!"</span>
            exit <span class="hljs-number">1</span>
          fi
</code></pre>
<p><strong>Automated scans check for:</strong></p>
<ul>
<li><p>Hardcoded API keys, tokens, or passwords</p>
</li>
<li><p>Insecure network configurations (allowing HTTP instead of HTTPS)</p>
</li>
<li><p>Weak cryptographic algorithms</p>
</li>
<li><p>Known vulnerabilities in third-party libraries</p>
</li>
<li><p>Improper SSL/TLS certificate validation</p>
</li>
<li><p>Insecure data storage (storing sensitive data in UserDefaults)</p>
</li>
<li><p>Excessive app permissions</p>
</li>
</ul>
<p><strong>Example output from an automated scan:</strong></p>
<pre><code class="lang-swift"><span class="hljs-type">Security</span> <span class="hljs-type">Scan</span> <span class="hljs-type">Results</span>:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[<span class="hljs-type">CRITICAL</span>] <span class="hljs-type">Hardcoded</span> <span class="hljs-type">API</span> <span class="hljs-type">Key</span> <span class="hljs-type">Found</span>
  <span class="hljs-type">File</span>: <span class="hljs-type">APIClient</span>.swift:<span class="hljs-number">15</span>
  <span class="hljs-type">Issue</span>: <span class="hljs-type">API</span> key <span class="hljs-string">"sk_live_abc123..."</span> detected <span class="hljs-keyword">in</span> source code

[<span class="hljs-type">HIGH</span>] <span class="hljs-type">Insecure</span> <span class="hljs-type">HTTP</span> <span class="hljs-type">Connection</span>
  <span class="hljs-type">File</span>: <span class="hljs-type">NetworkManager</span>.swift:<span class="hljs-number">42</span>
  <span class="hljs-type">Issue</span>: <span class="hljs-type">App</span> allows cleartext <span class="hljs-type">HTTP</span> traffic to api.example.com
  <span class="hljs-type">Fix</span>: <span class="hljs-type">Enforce</span> <span class="hljs-type">HTTPS</span> or add exception to <span class="hljs-type">Info</span>.plist <span class="hljs-keyword">if</span> <span class="hljs-keyword">required</span>

[<span class="hljs-type">MEDIUM</span>] <span class="hljs-type">Weak</span> <span class="hljs-type">Encryption</span> <span class="hljs-type">Algorithm</span>
  <span class="hljs-type">File</span>: <span class="hljs-type">DataEncryption</span>.swift:<span class="hljs-number">28</span>
  <span class="hljs-type">Issue</span>: <span class="hljs-type">Using</span> <span class="hljs-type">MD5</span> <span class="hljs-keyword">for</span> hashing (cryptographically broken)
  <span class="hljs-type">Fix</span>: <span class="hljs-type">Use</span> <span class="hljs-type">SHA</span>-<span class="hljs-number">256</span> or better

[<span class="hljs-type">LOW</span>] <span class="hljs-type">Outdated</span> <span class="hljs-type">Dependency</span>
  <span class="hljs-type">Library</span>: <span class="hljs-type">Alamofire</span> <span class="hljs-number">4.2</span>.<span class="hljs-number">0</span>
  <span class="hljs-type">Issue</span>: <span class="hljs-type">Known</span> vulnerability <span class="hljs-type">CVE</span>-<span class="hljs-number">2021</span>-<span class="hljs-number">12345</span>
  <span class="hljs-type">Fix</span>: <span class="hljs-type">Update</span> to version <span class="hljs-number">5.6</span>.<span class="hljs-number">0</span> or later
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
<span class="hljs-type">Build</span> <span class="hljs-type">Failed</span>: <span class="hljs-number">2</span> critical issues must be fixed before deployment
</code></pre>
<p><strong>2. Use MobSF (Mobile Security Framework) for Vulnerability Analysis</strong></p>
<p>MobSF is a free, automated tool that analyzes your iOS app for security issues:</p>
<pre><code class="lang-swift"># <span class="hljs-type">Install</span> and run <span class="hljs-type">MobSF</span> locally
docker pull opensecurity/mobile-security-framework-mobsf
docker run -it -p <span class="hljs-number">8000</span>:<span class="hljs-number">8000</span> opensecurity/mobile-security-framework-mobsf

# <span class="hljs-type">Upload</span> your .ipa file through the web interface at localhost:<span class="hljs-number">8000</span>
# <span class="hljs-type">MobSF</span> will analyze and provide a detailed security report
</code></pre>
<p>What MobSF checks:</p>
<ul>
<li><p>Binary analysis for hardcoded secrets</p>
</li>
<li><p>Insecure data storage patterns</p>
</li>
<li><p>Weak cryptographic implementations</p>
</li>
<li><p>Insecure network connections</p>
</li>
<li><p>Code quality and security best practices</p>
</li>
<li><p>Compliance with security standards</p>
</li>
</ul>
<p><strong>3. Conduct Regular Code Audits Using OWASP MSTG</strong></p>
<p>Use the OWASP Mobile Security Testing Guide as a checklist to audit your own code:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// Example: Following OWASP MSTG recommendations for secure storage</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SecureStorage</span> </span>{
    <span class="hljs-comment">// ❌ Insecure - UserDefaults is not encrypted</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">saveTokenInsecurely</span><span class="hljs-params">(<span class="hljs-number">_</span> token: String)</span></span> {
        <span class="hljs-type">UserDefaults</span>.standard.<span class="hljs-keyword">set</span>(token, forKey: <span class="hljs-string">"authToken"</span>)
    }

    <span class="hljs-comment">// ✅ Secure - Using Keychain as OWASP recommends</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">saveTokenSecurely</span><span class="hljs-params">(<span class="hljs-number">_</span> token: String)</span></span> <span class="hljs-keyword">throws</span> {
        <span class="hljs-keyword">let</span> data = token.data(using: .utf8)!
        <span class="hljs-keyword">let</span> query: [<span class="hljs-type">String</span>: <span class="hljs-type">Any</span>] = [
            kSecClass <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: kSecClassGenericPassword,
            kSecAttrAccount <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: <span class="hljs-string">"authToken"</span>,
            kSecValueData <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: data,
            kSecAttrAccessible <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
        ]

        <span class="hljs-type">SecItemDelete</span>(query <span class="hljs-keyword">as</span> <span class="hljs-type">CFDictionary</span>)
        <span class="hljs-keyword">let</span> status = <span class="hljs-type">SecItemAdd</span>(query <span class="hljs-keyword">as</span> <span class="hljs-type">CFDictionary</span>, <span class="hljs-literal">nil</span>)

        <span class="hljs-keyword">guard</span> status == errSecSuccess <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">throw</span> <span class="hljs-type">StorageError</span>.saveFailed
        }
    }
}
</code></pre>
<p><strong>OWASP MSTG Checklist for Self-Audit:</strong></p>
<ul>
<li><p>[ ] Are all sensitive data encrypted at rest?</p>
</li>
<li><p>[ ] Is HTTPS enforced for all network calls?</p>
</li>
<li><p>[ ] Are certificates properly validated?</p>
</li>
<li><p>[ ] Is sensitive data excluded from logs?</p>
</li>
<li><p>[ ] Are API keys and secrets not hardcoded?</p>
</li>
<li><p>[ ] Is user input validated and sanitized?</p>
</li>
<li><p>[ ] Are authentication tokens stored securely in Keychain?</p>
</li>
</ul>
<p><strong>4. Automated Dependency Scanning</strong></p>
<p>Monitor your dependencies continuously for newly discovered vulnerabilities:</p>
<pre><code class="lang-swift"># <span class="hljs-type">For</span> <span class="hljs-type">CocoaPods</span> projects
gem install cocoapods-audit
pod audit

# <span class="hljs-type">For</span> <span class="hljs-type">Swift</span> <span class="hljs-type">Package</span> <span class="hljs-type">Manager</span>
# <span class="hljs-type">Use</span> <span class="hljs-type">GitHub</span> <span class="hljs-type">Dependabot</span> (free <span class="hljs-keyword">for</span> <span class="hljs-keyword">public</span> repos) or
brew install swift-outdated
swift-outdated
</code></pre>
<p>And set up automated alerts with these tools:</p>
<ul>
<li><p><strong>GitHub Dependabot:</strong> Automatically creates PRs when vulnerable dependencies are detected (free)</p>
</li>
<li><p><strong>Snyk</strong>: Free tier available for open-source projects</p>
</li>
<li><p><strong>OWASP Dependency-Check:</strong> Free command-line tool</p>
</li>
</ul>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Developing secure iOS apps using Swift is all about forward-thinking. You should do all you can to avoid these common errors, like insecure storage of data, poor network communication, hard-coded secrets, or poor authentication.</p>
<p>Using Keychain for confidential information, requiring HTTPS, input validation, and multifactor authentication are all steps that decrease risk.</p>
<p>Regular testing for security vulnerabilities and limiting third-party library use can also further enhance your app's security.</p>
<p>Security is a continuous responsibility. Swift provides tools, but the developers need to apply those tools carefully. Security being tackled right from the start protects users' information, creates trust, and protects the reputation of the application.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Embedded Swift: A Modern Approach to Low-Level Programming ]]>
                </title>
                <description>
                    <![CDATA[ Embedded programming has long been dominated by C and C++, powering everything from microcontrollers to real-time systems. While these languages offer unmatched low-level control, they also introduce persistent challenges, manual memory management, u... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/embedded-swift-a-modern-approach-to-low-level-programming/</link>
                <guid isPermaLink="false">688d5fc7d30be1cecdacf767</guid>
                
                    <category>
                        <![CDATA[ embedded systems ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Firmware Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ C ]]>
                    </category>
                
                    <category>
                        <![CDATA[ C++ ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Programming Blogs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ memory-management ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programming languages ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Soham Banerjee ]]>
                </dc:creator>
                <pubDate>Sat, 02 Aug 2025 00:45:59 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1754090186842/80a42dca-f2c4-49de-b704-2e90134c6397.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Embedded programming has long been dominated by C and C++, powering everything from microcontrollers to real-time systems. While these languages offer unmatched low-level control, they also introduce persistent challenges, manual memory management, unsafe pointer operations, and subtle logic bugs stemming from weak type systems and undefined behavior.</p>
<p>With the release of Swift 6 and its new Embedded Swift compilation mode, developers now have access to a modern, memory-safe, and performant alternative that’s tailored specifically for resource-constrained systems.</p>
<p>While languages like Rust have also emerged to address these issues, Embedded Swift brings the clarity and safety of Swift to microcontroller environments, without giving up on determinism, binary size, or hardware access.</p>
<p>This article introduces Embedded Swift and explores how it compares to traditional C/C++ development. We’ll cover its key features, programming and memory models, how to set up the toolchain for STM32 microcontrollers, and how to link Swift with existing C drivers.</p>
<p>Along the way, we’ll examine performance trade-offs, growing ecosystem support, and the broader industry movement toward memory-safe languages. As I hope you’ll see, Swift is a serious contender in the future of embedded development.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To get the most out of this article, you should have a basic understanding of programming in Swift and C. Familiarity with embedded hardware platforms and firmware development concepts will also be helpful.</p>
<p>If you're new to embedded systems, consider reviewing this <a target="_blank" href="https://www.freecodecamp.org/news/learn-embedded-systems-firmware-basics-handbook-for-devs/">introductory guide to embedded firmware</a> to build foundational knowledge before diving into Embedded Swift.</p>
<h2 id="heading-scope">Scope</h2>
<p>This article is intended as a practical introduction to Embedded Swift. It covers:</p>
<ul>
<li><p>An overview of Embedded Swift and its key language features</p>
</li>
<li><p>Swift’s programming and memory model in an embedded context</p>
</li>
<li><p>Setting up the Embedded Swift toolchain on macOS for STM32 microcontrollers</p>
</li>
<li><p>Interoperability with C code and linking to existing low-level drivers</p>
</li>
<li><p>A look at memory and instruction-level performance</p>
</li>
<li><p>Future directions and use cases for Embedded Swift</p>
</li>
</ul>
<p>Note that this article does not provide a full tutorial on the Swift language itself. While the primary focus is on STM32, similar principles apply to other supported platforms such as ESP32, Raspberry Pi Pico, and nRF52.</p>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-swift-what-is-embedded-swift">What is Swift? What is Embedded Swift?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-swift-programming-model">Swift Programming Model</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-swift-memory-management">Swift Memory Management</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-memory-and-instruction-cycle-comparison">Memory and Instruction Cycle Comparison</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-setup-embedded-swift">How to Setup Embedded Swift</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-c-swift-linkages">C-Swift Linkages:</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-future-work">Future Work</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-swift-what-is-embedded-swift">What is Swift? What is Embedded Swift?</h2>
<p>Swift is a modern programming language developed by Apple that combines the performance of compiled languages with the expressiveness and safety of modern language design. While Swift was originally created for iOS and macOS development, it has evolved into a powerful general-purpose language used in server-side development, systems programming, and increasingly, embedded systems.</p>
<p>Embedded Swift is a special compilation mode introduced in Swift 6 that brings the benefits of Swift to resource-constrained platforms like microcontrollers. It lets developers use a safe, high-level language while still producing compact, deterministic, and performant binaries suitable for embedded applications.</p>
<h3 id="heading-key-features-of-swift">Key Features of Swift</h3>
<p>Embedded Swift retains many of the powerful language features that make Swift an attractive alternative to C/C++ in embedded development:</p>
<p><strong>Type Safety</strong>: Swift uses a strong static type system, which prevents many programming errors at compile time. Unlike C, where type mismatches can result in undefined behavior, Swift ensures all types are used correctly before code even runs.</p>
<p><strong>Strict Type Checking</strong>: Swift doesn't allow implicit type conversions that could lose data or cause unexpected behavior. For example:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// This won't compile in Swift</span>
<span class="hljs-keyword">let</span> integer: <span class="hljs-type">Int</span> = <span class="hljs-number">42</span>
<span class="hljs-keyword">let</span> decimal: <span class="hljs-type">Double</span> = <span class="hljs-number">3.14</span>
<span class="hljs-keyword">let</span> result = integer + decimal  <span class="hljs-comment">// Error: Cannot convert value of type 'Int' to expected argument type 'Double'</span>

<span class="hljs-comment">// You must be explicit about conversions</span>
<span class="hljs-keyword">let</span> result = <span class="hljs-type">Double</span>(integer) + decimal  <span class="hljs-comment">// Correct</span>
</code></pre>
<p><strong>Non-nullable Types by Default</strong>: In C, pointers can be null by default, which introduces risk. In Swift, variables cannot be nil unless explicitly marked as optionals:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> name: <span class="hljs-type">String</span> = <span class="hljs-string">"John"</span>
name = <span class="hljs-literal">nil</span>  <span class="hljs-comment">// Compile error - String cannot be nil</span>

<span class="hljs-keyword">var</span> optionalName: <span class="hljs-type">String?</span> = <span class="hljs-string">"John"</span>
optionalName = <span class="hljs-literal">nil</span>  <span class="hljs-comment">// This is allowed</span>
</code></pre>
<h4 id="heading-memory-safety-via-arc-covered-in-detail-later">Memory Safety via ARC (Covered in detail later):</h4>
<p>Swift manages memory automatically using Automatic Reference Counting (ARC). Unlike manual memory management in C/C++, ARC handles object lifecycles efficiently without unpredictable garbage collection pauses. We'll cover ARC and its impact in embedded contexts in a dedicated section later.</p>
<p><strong>Modern Syntax</strong>:<br>Swift's syntax is clean, consistent, and designed for readability. It supports modern paradigms including:</p>
<ul>
<li><p>Functional programming (map, filter, reduce)</p>
</li>
<li><p>Generics (type-safe abstractions)</p>
</li>
<li><p>Protocol-Oriented Programming (discussed in the next section)</p>
</li>
</ul>
<p>These features allow you to write more expressive and maintainable code compared to procedural C or inheritance-heavy C++.</p>
<p><strong>Performance</strong>:<br>Swift is designed to perform on par with C++ in many scenarios. Optimizations such as inlining, dead code elimination, and static dispatch help ensure that high-level abstractions don’t compromise performance. In embedded mode, Swift disables features like runtime reflection and dynamic dispatch to further reduce overhead.</p>
<p>To fully leverage Swift for embedded development, it's important to understand its programming model. Unlike C’s procedural approach or C++’s class-heavy design, Swift promotes protocol-oriented programming and composition, which offers both flexibility and safety in embedded system design.</p>
<h2 id="heading-swift-programming-model">Swift Programming Model</h2>
<p>Swift embraces a multi-paradigm programming model that blends object-oriented, functional, and protocol-oriented programming, all underpinned by strong type safety and memory safety.</p>
<p>For embedded developers coming from C or C++, this model may feel different at first. But it provides a more modular and testable way to build complex systems, something especially valuable in embedded applications where hardware abstraction and strict reliability are critical.</p>
<h3 id="heading-protocol-oriented-programming-pop">Protocol-Oriented Programming (POP)</h3>
<p>Swift emphasizes protocols over inheritance, encouraging developers to define behaviors through protocols and implement them using value types like <code>struct</code> and <code>enum</code>, rather than relying heavily on classes.</p>
<p>This philosophy favors composition over inheritance, allowing you to build complex functionality by combining smaller, well-defined components.</p>
<p>Key Concepts<strong>:</strong></p>
<ul>
<li><p><code>protocol</code> defines required behavior.</p>
</li>
<li><p>Protocol extensions provide default behavior.</p>
</li>
<li><p>Prefer value semantics using <code>struct</code>.</p>
</li>
</ul>
<p>Example<strong>:</strong></p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">protocol</span> <span class="hljs-title">Speakable</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">speak</span><span class="hljs-params">()</span></span>
}

<span class="hljs-class"><span class="hljs-keyword">extension</span> <span class="hljs-title">Speakable</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">speak</span><span class="hljs-params">()</span></span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"Default sound"</span>)
    }
}

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Dog</span>: <span class="hljs-title">Speakable</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">speak</span><span class="hljs-params">()</span></span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"Woof!"</span>)
    }
}
</code></pre>
<p>Embedded Swift uses protocols with static dispatch. With static dispatch, the compiler knows the exact memory address of the function to call and can generate a direct jump instruction. There's no runtime lookup, no indirection, and no uncertainty.</p>
<h4 id="heading-why-pop-matters-for-embedded-systems">Why POP Matters for Embedded Systems</h4>
<p>First, you get flexible hardware extraction. Protocols make it easy to define interfaces for hardware components, allowing for mock implementations during testing or platform-specific variations.</p>
<p>Second, you have nice low overhead. Embedded Swift uses static dispatch for protocols, meaning there’s no runtime lookup, and calls are resolved at compile time for maximum performance.</p>
<p>Also, <code>struct</code> and <code>enum</code> types avoid heap allocations, making code more efficient and predictable in low-memory environments.</p>
<p>Now that we’ve explored how Swift’s programming model enables safer and more modular embedded code, let’s turn to another critical piece of the puzzle: memory management. Swift’s use of Automatic Reference Counting (ARC) replaces manual memory handling and offers important benefits, and tradeoffs, for embedded systems.</p>
<h2 id="heading-swift-memory-management">Swift Memory Management</h2>
<p>One of Swift’s most impactful features, especially in the context of embedded systems, is its use of Automatic Reference Counting (ARC) for memory management. Unlike C/C++, where memory must be manually allocated and freed using <code>malloc</code> and <code>free</code>, Swift automates this process while maintaining deterministic performance.</p>
<p>This automation significantly reduces the risk of common memory-related bugs like leaks, dangling pointers, or use-after-free errors, all of which are notorious in low-level C code.</p>
<h3 id="heading-how-arc-works">How ARC works</h3>
<p>Swift supports ARC not only for the Cocoa Touch API's but for all APIs, providing a streamlined approach to memory management. Unlike garbage collection systems that can cause unpredictable pauses, ARC works deterministically at compile time and runtime to manage memory.</p>
<p>ARC automatically tracks and manages the lifetime of objects in memory based on how many references point to them.</p>
<ul>
<li><p>Reference Counting: Every object has a counter that tracks how many strong references point to it.</p>
</li>
<li><p>Retain / Release: The compiler inserts <code>retain</code> and <code>release</code> calls automatically during assignment and deinitialization.</p>
</li>
<li><p>Immediate Deallocation: When the reference count reaches zero, the object is deallocated immediately.</p>
</li>
<li><p>Deterministic: Unlike garbage collectors, ARC doesn’t introduce unpredictable pauses or runtime scanning.</p>
</li>
</ul>
<p>Swift offers multiple reference types to give you precise control over memory behavior and prevent cycles:</p>
<p><strong>Strong References</strong> (default)</p>
<ul>
<li><p>Keeps the referenced object alive.</p>
</li>
<li><p>Used in most cases.</p>
</li>
</ul>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MotorController</span> </span>{
    <span class="hljs-keyword">var</span> sensor: <span class="hljs-type">SensorData?</span>  <span class="hljs-comment">// Strong reference</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">updateReading</span><span class="hljs-params">(newData: SensorData)</span></span> {
        <span class="hljs-keyword">self</span>.sensor = newData  <span class="hljs-comment">// Previous sensor data automatically deallocated</span>
    }
}
</code></pre>
<p><strong>Weak References</strong></p>
<ul>
<li><p>Used to break reference cycles (especially in two-way object relationships).</p>
</li>
<li><p>Automatically becomes <code>nil</code> when the referenced object is deallocated.</p>
</li>
</ul>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Device</span> </span>{
    <span class="hljs-keyword">var</span> controller: <span class="hljs-type">MotorController?</span>

    <span class="hljs-keyword">deinit</span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"Device deallocated"</span>)
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MotorController</span> </span>{
    <span class="hljs-keyword">weak</span> <span class="hljs-keyword">var</span> device: <span class="hljs-type">Device?</span>  <span class="hljs-comment">// ← Weak reference breaks the cycle</span>

    <span class="hljs-keyword">deinit</span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"MotorController deallocated"</span>)
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">breakCycle</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">let</span> device = <span class="hljs-type">Device</span>()
    <span class="hljs-keyword">let</span> controller = <span class="hljs-type">MotorController</span>()

    device.controller = controller
    controller.device = device  <span class="hljs-comment">// ← This is now a weak reference</span>

    <span class="hljs-comment">// When this function ends, both objects are properly deallocated</span>
}

breakCycle()
<span class="hljs-comment">// Output:</span>
<span class="hljs-comment">// Device deallocated</span>
<span class="hljs-comment">// MotorController deallocated</span>
</code></pre>
<p><strong>Unowned References</strong></p>
<ul>
<li><p>Non-optional version of <code>weak</code>.</p>
</li>
<li><p>Assumes the object will never be deallocated while still in use.</p>
</li>
<li><p>More lightweight than <code>weak</code>, but unsafe if misused.</p>
</li>
</ul>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SensorSystem</span> </span>{
    <span class="hljs-keyword">unowned</span> <span class="hljs-keyword">let</span> controller: <span class="hljs-type">MotorController</span>  <span class="hljs-comment">// unowned reference</span>

    <span class="hljs-keyword">init</span>(controller: <span class="hljs-type">MotorController</span>) {
        <span class="hljs-keyword">self</span>.controller = controller
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MotorController</span> </span>{
    <span class="hljs-keyword">var</span> sensorSystem: <span class="hljs-type">SensorSystem?</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">setupSensors</span><span class="hljs-params">()</span></span> {
        sensorSystem = <span class="hljs-type">SensorSystem</span>(controller: <span class="hljs-keyword">self</span>)
    }

    <span class="hljs-keyword">deinit</span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"MotorController deallocated"</span>)
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">testUnowned</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">let</span> controller = <span class="hljs-type">MotorController</span>()
    controller.setupSensors()
    <span class="hljs-comment">// sensorSystem deallocates before controller ends</span>
}

testUnowned()
<span class="hljs-comment">// Output: MotorController deallocated</span>
</code></pre>
<h3 id="heading-arc-overhead-in-embedded-systems">ARC Overhead in Embedded Systems</h3>
<p>While ARC provides safety benefits, it does introduce some overhead compared to manual memory management:</p>
<h4 id="heading-memory-overhead">Memory Overhead:</h4>
<p>ARC-managed class instances in Swift typically include an additional 4 or 8 bytes to store reference count metadata, depending on the system architecture, 4 bytes on 32-bit systems and 8 bytes on 64-bit systems. This metadata allows the runtime to track how many active references exist to a given object and deallocate it when no references remain. When developers use weak or unowned references, the memory footprint increases further. These references require additional data structures, such as side tables or tracking mechanisms, to manage object liveness and cleanup. In the case of weak references specifically, Swift maintains zeroing weak reference tables that automatically null out pointers once the referenced object is deallocated, ensuring memory safety.</p>
<h4 id="heading-cpu-overhead">CPU Overhead:</h4>
<p>ARC introduces some runtime overhead due to retain and release operations, which are inserted automatically during reference assignments. These operations involve incrementing or decrementing the reference count and are especially common in code that passes objects between functions or stores them in collections. To ensure thread safety, these updates are typically implemented using atomic operations, which add further instruction cycles. In complex object graphs, ARC may also engage in cycle detection and cleanup through the use of weak references to prevent memory leaks caused by strong reference cycles. While Swift's ARC provides deterministic and efficient memory management, it does so with both memory and CPU costs that developers should consider carefully, especially in performance-critical embedded systems.</p>
<h3 id="heading-type-safety-and-error-prevention">Type Safety and Error Prevention</h3>
<p>Swift's type system prevents many common errors that plague C/C++ programs:</p>
<ul>
<li><p><strong>Buffer Overflows</strong>: Swift arrays are bounds-checked, preventing buffer overflow vulnerabilities that are common in C.</p>
</li>
<li><p><strong>Null Pointer Dereferences</strong>: Swift's optional types make null pointer dereferences impossible at compile time.</p>
</li>
<li><p><strong>Use After Free</strong>: Swift's ownership model prevents use-after-free errors that can cause crashes or security vulnerabilities.</p>
</li>
</ul>
<p>Now that we’ve covered Swift's memory model and ARC behavior, let’s explore how it compares to C in terms of memory usage and instruction cycles, a crucial aspect when evaluating Embedded Swift for real-world deployment.</p>
<h2 id="heading-memory-and-instruction-cycle-comparison">Memory and Instruction Cycle Comparison</h2>
<p>Understanding the performance characteristics of Swift versus C is essential for embedded systems, where every instruction cycle and byte of memory matters. While Swift brings advantages like safety and expressiveness, these benefits come with certain trade-offs in terms of memory usage and runtime behavior that embedded developers must evaluate carefully.</p>
<h3 id="heading-memory-management">Memory Management:</h3>
<p>Swift uses Automatic Reference Counting (ARC) to manage memory. ARC tracks the number of references to each object and deallocates it when no references remain. This eliminates the need for explicit <code>free()</code> calls but introduces overhead.</p>
<p>C, in contrast, uses manual memory management. Developers allocate memory using <code>malloc</code> and release it using <code>free</code>, or rely on the stack for most short-lived data.</p>
<p>The table below provides the memory management comparison between Swift and C:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>Swift (ARC)</strong></td><td><strong>C (Manual)</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Memory strategy</td><td>Automatic reference counting</td><td>Manual with <code>malloc</code>/<code>free</code></td></tr>
<tr>
<td>Overhead per object</td><td>4–8 bytes (for ref count)</td><td>None for stack; variable for heap</td></tr>
<tr>
<td>Deallocation</td><td>Deterministic, triggered by ARC</td><td>Developer-controlled</td></tr>
<tr>
<td>Weak reference support</td><td>Requires additional metadata</td><td>Not built-in</td></tr>
<tr>
<td>Thread safety</td><td>Atomic operations in ARC</td><td>Not guaranteed</td></tr>
<tr>
<td>Layout control</td><td>Limited, compiler-managed</td><td>Full control (via structs/pointers)</td></tr>
</tbody>
</table>
</div><p>Swift ensures safety through deterministic cleanup and predictable memory usage. But this comes at the cost of added memory and CPU overhead.</p>
<p>C’s approach offers complete control over memory layout and minimal runtime cost, but increases the risk of memory leaks and fragmentation without disciplined practices.</p>
<h3 id="heading-instruction-cycle-analysis">Instruction Cycle Analysis</h3>
<p>The safety features in Swift, such as bounds checking, optional unwrapping, and ARC updates, translate into additional CPU instructions. While this can impact performance, the Swift compiler is aggressive about optimization in release builds. For example, inlining and ARC elision can remove much of the overhead in performance-critical paths.</p>
<p>C has no built-in safety checks, allowing it to generate highly efficient, predictable code. Developers can even use inline assembly for tight control over performance.</p>
<p>The table below provides the instruction cycle comparison between Swift and C:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Instruction-Level Feature</strong></td><td><strong>Swift</strong></td><td><strong>C</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Reference count updates</td><td>2–4 instructions per assignment</td><td>N/A</td></tr>
<tr>
<td>Bounds checking</td><td>1–3 instructions per array access</td><td>None</td></tr>
<tr>
<td>Optional unwrapping</td><td>1–2 instructions per check</td><td>N/A</td></tr>
<tr>
<td>Method dispatch</td><td>Protocols introduce indirection</td><td>Direct calls or function pointers</td></tr>
<tr>
<td>Optimization potential</td><td>ARC elision, inlining, dead code removal</td><td>Full manual control, inline assembly</td></tr>
<tr>
<td>Predictability</td><td>High in optimized builds, with some abstraction overhead</td><td>Very high, minimal abstraction</td></tr>
</tbody>
</table>
</div><p>Although Swift inserts extra instructions for safety, much of this cost can be mitigated through compiler optimization.</p>
<p>C has no such features by default, making it ideal for applications where performance must be tightly controlled and the developer is willing to take full responsibility for safety.</p>
<h3 id="heading-instruction-count-comparison-swift-vs-c-loop-performance">Instruction Count Comparison: Swift vs C Loop Performance</h3>
<p>When evaluating Swift and C for embedded use, it's helpful to analyze instruction-level performance on basic operations, such as a loop that processes an array of floating-point numbers. This gives us a concrete sense of the computational cost of each language's safety and abstraction features.</p>
<p>Let’s consider a simple example: summing an array of <code>Float</code> values and returning the average. In Swift, the code uses a high-level <code>for-in</code> loop over an array:</p>
<p>Simple loop performance:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// Swift loop with safety checks</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">processData</span><span class="hljs-params">(<span class="hljs-number">_</span> data: [Float])</span></span> -&gt; <span class="hljs-type">Float</span> {
    <span class="hljs-keyword">var</span> sum: <span class="hljs-type">Float</span> = <span class="hljs-number">0.0</span>
    <span class="hljs-keyword">for</span> value <span class="hljs-keyword">in</span> data {  <span class="hljs-comment">// Iterator with bounds checking</span>
        sum += value     <span class="hljs-comment">// Safe arithmetic</span>
    }
    <span class="hljs-keyword">return</span> sum / <span class="hljs-type">Float</span>(data.<span class="hljs-built_in">count</span>)  <span class="hljs-comment">// Safe division</span>
}
<span class="hljs-comment">// Estimated: ~8-10 instructions per iteration</span>
</code></pre>
<p>Although elegant and safe, this loop includes several safety mechanisms:</p>
<ol>
<li><p>Bounds checking on every array access</p>
</li>
<li><p>Reference counting if <code>data</code> is passed as a reference type</p>
</li>
<li><p>Overflow protection in debug mode</p>
</li>
<li><p>Optional handling or runtime checks if <code>data</code> might be empty</p>
</li>
</ol>
<p>These checks introduce runtime overhead, resulting in an estimated 8–10 instructions per iteration on most platforms (depending on optimization level and target architecture). In release builds, Swift aggressively inlines and strips redundant checks, but some level of abstraction cost remains, especially compared to raw memory access in C.</p>
<p>Now, compare that to its equivalent in C:</p>
<pre><code class="lang-c"><span class="hljs-comment">// C loop without safety checks</span>
<span class="hljs-function"><span class="hljs-keyword">float</span> <span class="hljs-title">process_data</span><span class="hljs-params">(<span class="hljs-keyword">float</span>* data, <span class="hljs-keyword">int</span> count)</span> </span>{
    <span class="hljs-keyword">float</span> sum = <span class="hljs-number">0.0f</span>;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; count; i++) {  <span class="hljs-comment">// Direct pointer arithmetic</span>
        sum += data[i];                <span class="hljs-comment">// Direct memory access</span>
    }
    <span class="hljs-keyword">return</span> sum / count;  <span class="hljs-comment">// Direct division (no safety check)</span>
}
<span class="hljs-comment">// Estimated: ~4-5 instructions per iteration</span>
</code></pre>
<p>This version performs direct memory access with pointer arithmetic, no bounds checks, and no type safety. The C code is lower-level, with fewer runtime checks, and compiles down to just 4–5 instructions per iteration, depending on the target CPU and compiler flags. It is lean and fast, ideal for cycles-per-instruction-critical scenarios.</p>
<p>The table below shows the comparison of single loop performance between Swift and C:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Swift</td><td>C</td></tr>
</thead>
<tbody>
<tr>
<td>Array access</td><td>Bounds-checked</td><td>Direct pointer access</td></tr>
<tr>
<td>Loop iteration</td><td>High-level iterator abstraction</td><td>Raw loop with pointer increment</td></tr>
<tr>
<td>Instruction count (per loop)</td><td>~8–10 (in debug), ~6–8 (in release)</td><td>~4–5</td></tr>
<tr>
<td>Division</td><td>Safe (avoids divide-by-zero in dev)</td><td>Direct</td></tr>
<tr>
<td>Overflow behavior</td><td>Checked in debug, unchecked in release</td><td>Unchecked</td></tr>
<tr>
<td>Readability and safety</td><td>High</td><td>Low</td></tr>
<tr>
<td>Performance</td><td>Lower (but optimizable)</td><td>Higher (manual)</td></tr>
</tbody>
</table>
</div><p>Now that we’ve compared Swift and C in terms of memory and cycle costs, let’s move into the practical side: how to set up Embedded Swift on an STM32 platform and get started with real-world development.</p>
<h2 id="heading-how-to-setup-embedded-swift">How to Setup Embedded Swift</h2>
<p>In this section, we'll walk through how to configure and use Embedded Swift for development on STM32 microcontrollers. STM32 is a popular family of ARM Cortex-M–based microcontrollers, commonly used in industrial, consumer, and IoT applications.</p>
<h3 id="heading-prerequisites-1">Prerequisites</h3>
<p><strong>Required Software:</strong></p>
<ul>
<li><p>Swift Development Snapshot (includes the Embedded Swift toolchain)</p>
</li>
<li><p>Swiftly - Easiest way to manage and install swift toolchains</p>
</li>
<li><p>Swiftc - Swift Compiler command-line tool</p>
</li>
<li><p>Python3 - Required to run scripts to convert Mach-O to binary files</p>
</li>
<li><p>Git (to clone sample repositories) like <a target="_blank" href="https://github.com/swiftlang/swift-embedded-examples">https://github.com/swiftlang/swift-embedded-examples</a></p>
</li>
<li><p>A Unix-like development environment (macOS is currently best supported)</p>
</li>
</ul>
<p><strong>Target Hardware:</strong> This guide focuses on STM32 microcontrollers, which are widely used in embedded applications and have excellent community support.</p>
<p>This guide walks you through the full setup process, from installing the required Swift toolchain to flashing the final binary onto your board. We’ll begin by installing the Swift Development Snapshot using Swiftly, a simple command-line utility for managing Swift toolchains. From there, we’ll configure the build system, set up the correct board variant, customize the build script, and compile the Swift and C source code into a binary. Finally, we’ll flash the firmware onto the STM32 using standard tools</p>
<h3 id="heading-install-swift-development-snapshot">Install Swift Development Snapshot</h3>
<p>The easiest way to install and manage Embedded Swift toolchains is by using the swiftly tool, which simplifies downloading and using Swift snapshots.</p>
<h4 id="heading-macos-installation">macOS Installation:</h4>
<p>The below steps will help install the Swift embedded toolchain:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Using Swiftly (Recommended)</span>
curl -O https://download.swift.org/swiftly/darwin/swiftly.pkg
installer -pkg swiftly.pkg -target CurrentUserHomeDirectory
~/.swiftly/bin/swiftly init --quiet-shell-followup
<span class="hljs-built_in">source</span> <span class="hljs-string">"<span class="hljs-variable">${SWIFTLY_HOME_DIR:-<span class="hljs-variable">$HOME</span>/.swiftly}</span>/env.sh"</span>

<span class="hljs-comment"># Install and use development snapshot</span>
swiftly install main-snapshot
swiftly use main-snapshot

<span class="hljs-comment"># Verify installation</span>
swift --version
</code></pre>
<p>You can clone this Github example repository:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/swiftlang/swift-embedded-examples.git 
<span class="hljs-built_in">cd</span> swift-embedded-examples/projects/stm32-blink
</code></pre>
<p>The stm32-blink contains:</p>
<ul>
<li><p>Swift code that toggles GPIOs</p>
</li>
<li><p>A C startup file with vector table</p>
</li>
<li><p>A build.sh script that uses swiftc, clang, and a custom linker setup</p>
</li>
</ul>
<h3 id="heading-setup-the-stm32-board">Setup the STM32 Board</h3>
<p>Tell the build script which STM32 board is being used:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> STM_BOARD=STM32F746G_DISCOVERY
</code></pre>
<p>You can add your own board variant by defining the appropriate memory map and compiler flags in the script.</p>
<h3 id="heading-modify-buildsh-optional">Modify build.sh (Optional)</h3>
<p>Ensure the script correctly locates the following:</p>
<ul>
<li><p>swiftc: should point to the toolchain you installed with Swiftly</p>
</li>
<li><p>clang: can be macOS’s default Clang</p>
</li>
<li><p>libBuiltin.a, crt0.s, and macho2bin.py: used to provide minimal runtime support and convert output to flashable binaries</p>
</li>
</ul>
<p>If needed, update these paths:</p>
<pre><code class="lang-bash">SWIFT_EXEC=<span class="hljs-variable">${SWIFT_EXEC:-$(swiftly which swiftc)}</span>
CLANG_EXEC=<span class="hljs-variable">${CLANG_EXEC:-$(xcrun -f clang)}</span>
PYTHON_EXEC=<span class="hljs-variable">${PYTHON_EXEC:-$(which python3)}</span>
</code></pre>
<p>Ensure the linker flags match your target’s flash and RAM sizes.</p>
<h3 id="heading-build-and-flash-the-project">Build and Flash the Project:</h3>
<p>Run:</p>
<pre><code class="lang-bash">./build.sh
</code></pre>
<p>This compiles Swift and C code, links them, and produces a blink.bin file.</p>
<p>If successful, you’ll see:</p>
<pre><code class="lang-bash">.build/blink.bin  <span class="hljs-comment"># ready to flash Step 6: Flash the Firmware to STM32</span>
</code></pre>
<p>Use ST-Link tools or openocd to flash your board. Example using st-flash:</p>
<pre><code class="lang-bash">brew install stlink
st-flash write .build/blink.bin 0x8000000
</code></pre>
<p>You should now see an LED blinking.</p>
<p><a target="_blank" href="https://docs.swift.org/embedded/documentation/embedded/stm32baremetalguide">Here’s</a> a more detailed step by step approach to writing a bare metal code on STM32. For comprehensive installation guides covering other platforms (Raspberry Pi Pico, ESP32, nRF52), detailed IDE configuration, troubleshooting, and advanced examples, you can check out the official documentation:</p>
<ul>
<li><p>Complete Setup Guide: <a target="_blank" href="https://docs.swift.org/embedded/documentation/embedded/installembeddedswift/">Install Embedded Swift</a></p>
</li>
<li><p>Platform Examples: <a target="_blank" href="https://github.com/apple/swift-embedded-examples">Swift Embedded Examples Repository</a></p>
</li>
<li><p>Getting Started Tutorial: <a target="_blank" href="https://docs.swift.org/embedded/documentation/embedded">Embedded Swift on Microcontrollers</a></p>
</li>
</ul>
<p>Now that we’ve set up Embedded Swift and explored how to build and run an example project, let’s look at a critical real-world scenario: interfacing Swift with low-level C drivers.</p>
<h2 id="heading-c-swift-linkages">C-Swift Linkages</h2>
<p>In many embedded projects, low-level hardware drivers are written in C because of its close-to-metal control and widespread ecosystem support. Embedded Swift supports seamless interoperability with C, which lets you reuse existing C libraries and drivers, write hardware control logic in C, and implement higher-level application logic in Swift.</p>
<p>This hybrid model lets you combine Swift’s safety and productivity with C’s hardware-level control, with no runtime overhead or object translation.</p>
<p>Let’s walk through an example where a low-level sensor driver is implemented in C and the application logic is written in Swift.</p>
<h3 id="heading-c-header-file-sensordriverh">C Header File (sensor_driver.h):</h3>
<p>This C header file defines the public interface for a low-level sensor driver. It includes standard fixed-width integer types and declares four functions:</p>
<ul>
<li><p>sensor_init(): Initializes the hardware sensor</p>
</li>
<li><p>sensor_read_temperature() and sensor_read_humidity(): Read raw sensor values</p>
</li>
<li><p>sensor_delay_ms(): Delays execution for a given number of milliseconds</p>
</li>
</ul>
<p>This interface acts as a bridge between Swift and C. Swift will link to these functions by name, no wrappers or bindings required.</p>
<pre><code class="lang-c"><span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> SENSOR_DRIVER_H</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> SENSOR_DRIVER_H</span>

<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdint.h&gt;</span></span>

<span class="hljs-comment">// Low-level sensor driver functions</span>
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">sensor_init</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">uint32_t</span> <span class="hljs-title">sensor_read_temperature</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">uint32_t</span> <span class="hljs-title">sensor_read_humidity</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span></span>;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">sensor_delay_ms</span><span class="hljs-params">(<span class="hljs-keyword">uint32_t</span> milliseconds)</span></span>;

<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
</code></pre>
<h3 id="heading-c-implementation-sensordriverc">C Implementation (sensor_driver.c):</h3>
<p>This implementation assumes the sensor is memory-mapped at a fixed address (<code>0x40001000</code>). Each register, temperature, humidity, and control, is accessed by offset from that base address.</p>
<p>The <code>sensor_init</code>() function writes <code>0x01</code> to the control register, presumably enabling or starting the sensor hardware.</p>
<p>The <code>sensor_read_temperature()</code> method and <code>sensor_read_humidity()</code> method reads from memory-mapped registers and return the raw ADC values from the sensor.</p>
<p>The <code>sensor_delay_ms()</code> method performs a simple busy-wait loop using nop (no-operation) instructions to approximate a delay. This is suitable for short, coarse-grained delays in bare-metal contexts.</p>
<pre><code class="lang-c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"sensor_driver.h"</span></span>

<span class="hljs-comment">// Hardware register addresses</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> SENSOR_BASE_ADDR    0x40001000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> TEMP_REG_OFFSET     0x00</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> HUMIDITY_REG_OFFSET 0x04</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> CONTROL_REG_OFFSET  0x08</span>

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">sensor_init</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span> </span>{
    <span class="hljs-comment">// Initialize sensor hardware</span>
    <span class="hljs-keyword">volatile</span> <span class="hljs-keyword">uint32_t</span>* control_reg = (<span class="hljs-keyword">volatile</span> <span class="hljs-keyword">uint32_t</span>*)(SENSOR_BASE_ADDR + CONTROL_REG_OFFSET);
    *control_reg = <span class="hljs-number">0x01</span>; <span class="hljs-comment">// Enable sensor</span>
}

<span class="hljs-function"><span class="hljs-keyword">uint32_t</span> <span class="hljs-title">sensor_read_temperature</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span> </span>{
    <span class="hljs-keyword">volatile</span> <span class="hljs-keyword">uint32_t</span>* temp_reg = (<span class="hljs-keyword">volatile</span> <span class="hljs-keyword">uint32_t</span>*)(SENSOR_BASE_ADDR + TEMP_REG_OFFSET);
    <span class="hljs-keyword">return</span> *temp_reg;
}

<span class="hljs-function"><span class="hljs-keyword">uint32_t</span> <span class="hljs-title">sensor_read_humidity</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span> </span>{
    <span class="hljs-keyword">volatile</span> <span class="hljs-keyword">uint32_t</span>* humidity_reg = (<span class="hljs-keyword">volatile</span> <span class="hljs-keyword">uint32_t</span>*)(SENSOR_BASE_ADDR + HUMIDITY_REG_OFFSET);
    <span class="hljs-keyword">return</span> *humidity_reg;
}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">sensor_delay_ms</span><span class="hljs-params">(<span class="hljs-keyword">uint32_t</span> milliseconds)</span> </span>{
    <span class="hljs-comment">// Simple delay implementation</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">uint32_t</span> i = <span class="hljs-number">0</span>; i &lt; milliseconds * <span class="hljs-number">1000</span>; i++) {
        __asm__(<span class="hljs-string">"nop"</span>);
    }
}
</code></pre>
<h3 id="heading-swift-code-using-c-driver">Swift Code Using C Driver:</h3>
<p>To use these C functions from Swift, you declare them using <code>@_silgen_name</code>, which tells the Swift compiler to link directly to these symbol names at runtime.</p>
<p>The <code>SensorController</code> class encapsulates sensor-related logic. In its <code>init()</code> method, it calls the <code>sensor_init()</code> function defined in C to initialize the sensor hardware.</p>
<p>The <code>readSensors()</code> method reads the raw values from the C driver, converts them into human-readable units using helper functions, stores them internally, and returns the processed values.</p>
<p>The <code>convertTemperature()</code> and <code>convertHumidity()</code> conversion methods apply a basic linear formula to turn raw ADC values into temperature in Celsius and humidity in percentage, respectively. These formulas would be based on the specific sensor’s datasheet.</p>
<p>The <code>checkThresholds()</code> method applies simple threshold logic, a good example of where Swift’s readability and type safety shine. You could easily expand this logic to include error bounds, state machines, or alerts.</p>
<pre><code class="lang-swift"><span class="hljs-comment">// Import C driver functions</span>

<span class="hljs-comment">/*
These declarations match the C function signatures exactly. 
They allow Swift to invoke the C functions as if they were native Swift functions 
— with zero overhead.
*/</span>
@_silgen_name(<span class="hljs-string">"sensor_init"</span>)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">sensor_init</span><span class="hljs-params">()</span></span>

@_silgen_name(<span class="hljs-string">"sensor_read_temperature"</span>)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">sensor_read_temperature</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">UInt32</span>

@_silgen_name(<span class="hljs-string">"sensor_read_humidity"</span>)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">sensor_read_humidity</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">UInt32</span>

@_silgen_name(<span class="hljs-string">"sensor_delay_ms"</span>)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">sensor_delay_ms</span><span class="hljs-params">(<span class="hljs-number">_</span> ms: UInt32)</span></span>

<span class="hljs-comment">// Swift sensor controller using C driver</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SensorController</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> lastTemperature: <span class="hljs-type">Float</span> = <span class="hljs-number">0.0</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> lastHumidity: <span class="hljs-type">Float</span> = <span class="hljs-number">0.0</span>

    <span class="hljs-keyword">init</span>() {
        <span class="hljs-comment">// Initialize the C driver</span>
        sensor_init()
    }

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">readSensors</span><span class="hljs-params">()</span></span> -&gt; (temperature: <span class="hljs-type">Float</span>, humidity: <span class="hljs-type">Float</span>) {
        <span class="hljs-comment">// Read raw values from C driver</span>
        <span class="hljs-keyword">let</span> rawTemp = sensor_read_temperature()
        <span class="hljs-keyword">let</span> rawHumidity = sensor_read_humidity()

        <span class="hljs-comment">// Convert raw values to meaningful units in Swift</span>
        <span class="hljs-keyword">let</span> temperature = convertTemperature(rawValue: rawTemp)
        <span class="hljs-keyword">let</span> humidity = convertHumidity(rawValue: rawHumidity)

        <span class="hljs-comment">// Store for comparison</span>
        lastTemperature = temperature
        lastHumidity = humidity

        <span class="hljs-keyword">return</span> (temperature: temperature, humidity: humidity)
    }

    <span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">convertTemperature</span><span class="hljs-params">(rawValue: UInt32)</span></span> -&gt; <span class="hljs-type">Float</span> {
        <span class="hljs-comment">// Convert raw ADC value to Celsius</span>
        <span class="hljs-keyword">return</span> (<span class="hljs-type">Float</span>(rawValue) * <span class="hljs-number">3.3</span> / <span class="hljs-number">4095.0</span> - <span class="hljs-number">0.5</span>) * <span class="hljs-number">100.0</span>
    }

    <span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">convertHumidity</span><span class="hljs-params">(rawValue: UInt32)</span></span> -&gt; <span class="hljs-type">Float</span> {
        <span class="hljs-comment">// Convert raw ADC value to percentage</span>
        <span class="hljs-keyword">return</span> <span class="hljs-type">Float</span>(rawValue) * <span class="hljs-number">100.0</span> / <span class="hljs-number">4095.0</span>
    }

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">checkThresholds</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">Bool</span> {
        <span class="hljs-comment">// Swift logic for threshold checking</span>
        <span class="hljs-keyword">let</span> tempThreshold: <span class="hljs-type">Float</span> = <span class="hljs-number">25.0</span>
        <span class="hljs-keyword">let</span> humidityThreshold: <span class="hljs-type">Float</span> = <span class="hljs-number">60.0</span>

        <span class="hljs-keyword">return</span> lastTemperature &gt; tempThreshold || lastHumidity &gt; humidityThreshold
    }
}

<span class="hljs-comment">// Main application loop</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">Never</span> {
    <span class="hljs-keyword">let</span> sensorController = <span class="hljs-type">SensorController</span>()

    <span class="hljs-keyword">while</span> <span class="hljs-literal">true</span> {
        <span class="hljs-comment">// Read sensors using Swift controller with C driver</span>
        <span class="hljs-keyword">let</span> readings = sensorController.readSensors()

        <span class="hljs-comment">// Process data with Swift's type safety and expressiveness</span>
        <span class="hljs-keyword">if</span> sensorController.checkThresholds() {
            <span class="hljs-built_in">print</span>(<span class="hljs-string">"Warning: Temperature: \(readings.temperature)°C, Humidity: \(readings.humidity)%"</span>)
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">print</span>(<span class="hljs-string">"Normal: Temperature: \(readings.temperature)°C, Humidity: \(readings.humidity)%"</span>)
        }

        <span class="hljs-comment">// Delay using C driver function</span>
        sensor_delay_ms(<span class="hljs-number">1000</span>) <span class="hljs-comment">// 1 second delay</span>
    }
}
</code></pre>
<p>The <code>func main()</code> is the main event loop standard for embedded systems. It creates the sensor controller, reads sensor data in a loop, checks thresholds, and prints results accordingly. The loop includes a delay (via the C driver) to avoid hammering the sensor continuously.</p>
<p>In an actual embedded context, instead of using <code>print()</code>, you might blink an LED, send UART messages, or log data to memory.</p>
<p>With Embedded Swift and C now working together, let’s explore what lies ahead. The next section outlines ongoing improvements, emerging use cases, and research directions that are shaping the future of Embedded Swift.</p>
<h2 id="heading-future-work">Future Work</h2>
<p>Embedded Swift is still a young but rapidly evolving technology. Its modern language features, type safety, and performance make it an attractive option for embedded development, and ongoing work is expanding its capabilities, reach, and ecosystem.</p>
<h3 id="heading-ongoing-improvements">Ongoing Improvements</h3>
<p><strong>Compiler Optimizations</strong>: The Swift compiler team is actively improving code generation for embedded targets, including:</p>
<ul>
<li><p>Reducing binary size</p>
</li>
<li><p>Minimizing ARC overhead</p>
</li>
<li><p>Improving static dispatch performance</p>
</li>
</ul>
<p><strong>Hardware Support</strong>: Embedded Swift can target a wide variety of ARM and RISC-V microcontrollers, which are popular for building industrial applications. Support for additional architectures is being developed.</p>
<p><strong>Tooling Enhancements</strong>: Tooling support for Embedded Swift is still evolving, but several community-driven and open-source efforts are making development more accessible:</p>
<ul>
<li><p><strong>Build Systems</strong>: The Swift Embedded Working Group provides example projects that adapt Swift Package Manager (SwiftPM) for cross-compilation. Custom linker scripts and build helpers are available for platforms like STM32 and nRF52.</p>
</li>
<li><p><strong>Debugging Support</strong>: Developers can debug Embedded Swift programs using existing tools like GDB or OpenOCD, provided the build includes appropriate debug symbols. While not yet officially streamlined, this approach enables step-through debugging on real hardware.</p>
</li>
<li><p><strong>IDE Integration</strong>: There is no official IDE support yet, but some developers use VSCode with Swift syntax highlighting and external build tasks. These setups are still manual but serve as early prototypes for embedded workflows.</p>
</li>
</ul>
<h3 id="heading-emerging-use-cases">Emerging Use Cases</h3>
<p>There are a number of emerging use cases for embedded Swift. For example, Swift’s memory safety, type guarantees, and protocol-oriented design make it ideal for secure and scalable IoT devices, especially where firmware bugs could affect user safety or privacy.</p>
<p>The automotive sector is also exploring Swift for infotainment systems, driver assistance features, and safety-critical logic (where deterministic execution and safety matter).</p>
<p>Swift’s expressive syntax and compile-time safety make it suitable for industrial automation – think real-time control loops, sensor fusion systems, and edge devices in smart manufacturing.</p>
<p>It’s also useful for medical devices, as it aligns well with strict medical regulations around memory safety, type guarantees, and predictable resource usage.</p>
<h3 id="heading-community-and-ecosystem">Community and Ecosystem</h3>
<h4 id="heading-open-source-projects">Open Source Projects</h4>
<p>The Swift Embedded working group maintains <a target="_blank" href="https://github.com/swiftlang/swift-embedded-examples">example repositories</a> showcasing how to use Embedded Swift on microcontrollers such as STM32, nRF52, and ESP32. Early-stage libraries for UART, GPIO, and basic peripherals are emerging, though the ecosystem is still young compared to C or Rust.</p>
<h4 id="heading-learning-resources">Learning Resources</h4>
<p>While <a target="_blank" href="https://docs.swift.org/embedded/documentation/embedded">Embedded Swift</a> is not yet widely taught in formal curricula, community tutorials and exploratory projects (for example, Swift for Arduino) are lowering the barrier for hobbyists and independent learners. As tooling matures, educational adoption is likely to follow.</p>
<h4 id="heading-industry-interest">Industry Interest</h4>
<p>Embedded Swift is beginning to draw attention from developers and companies looking for safer, more maintainable alternatives to C. Although large-scale adoption remains limited, use cases like rapid prototyping, IoT development, and internal experimentation are gaining traction.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Embedded Swift represents a major step forward in embedded programming. By combining the power and safety of Swift with the low-level control needed for microcontrollers, it offers an exciting alternative to traditional C and C++ development.</p>
<p>While C will remain essential for hardware-level programming and performance-critical paths, Swift brings compelling advantages to many embedded scenarios:</p>
<ul>
<li><p><strong>Memory safety</strong>: Swift eliminates entire categories of bugs such as buffer overflows, use-after-free, and null pointer dereferencing.</p>
</li>
<li><p><strong>Type safety</strong>: Many logic errors are caught at compile time, long before they can cause runtime failures.</p>
</li>
<li><p><strong>Modern language features</strong>: Developers can use functional paradigms, generics, and protocol-oriented design even in embedded code.</p>
</li>
<li><p><strong>C interoperability</strong>: Swift works seamlessly with existing C libraries, allowing gradual adoption without rewriting low-level drivers.</p>
</li>
<li><p><strong>Developer productivity</strong>: Clear syntax, automatic memory management, and strong tooling lead to faster development and easier maintenance.</p>
</li>
</ul>
<p>Government and regulatory bodies are increasingly encouraging or mandating the use of memory-safe programming languages to reduce vulnerabilities in critical software systems. For example:</p>
<ul>
<li><p>In 2022, the <a target="_blank" href="https://media.defense.gov/2025/Jun/23/2003742198/-1/-1/0/CSI_MEMORY_SAFE_LANGUAGES_REDUCING_VULNERABILITIES_IN_MODERN_SOFTWARE_DEVELOPMENT.PDF"><strong>U.S. National Security Agency (NSA)</strong></a> recommended moving away from unsafe languages like C/C++ for new software projects, promoting memory-safe alternatives.</p>
</li>
<li><p>In June 2025, the NSA and CISA released a joint Cybersecurity Information Sheet titled “<a target="_blank" href="https://www.nsa.gov/Press-Room/Press-Releases-Statements/Press-Release-View/Article/4223298/nsa-and-cisa-release-csi-highlighting-importance-of-memory-safe-languages-in-so/">Memory Safe Languages: Reducing Vulnerabilities in Modern Software Development</a>”, which emphasized that memory safety flaws remain a persistent risk, and organizations should develop strategies to adopt memory-safe programming languages in new systems.</p>
</li>
<li><p>The <a target="_blank" href="https://www.trust-in-soft.com/resources/blogs/memory-safety-is-key-the-shift-in-u.s.-cyber-standards"><strong>U.S. Cybersecurity and Infrastructure Security Agency (CISA)</strong></a> and <a target="_blank" href="https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-218.pdf"><strong>NIST</strong></a> have echoed similar guidance in the context of national cybersecurity.</p>
</li>
</ul>
<p>While these documents do not mention Swift explicitly, Swift's strong type system, ARC-based memory model, and compile-time safety guarantees align closely with the goals outlined in these recommendations. As such, it offers a practical, developer-friendly path toward safer embedded development.</p>
<p>Swift may not be the right fit for every embedded system. In applications where every byte of memory or instruction cycle is critical, real-time guarantees are hard requirements, or toolchain maturity is essential (for example, RTOS integration, static analyzers), C or Rust may still be preferred.</p>
<p>But in many modern embedded applications, especially those involving rapid prototyping, fast product iteration, safety-critical or maintainable firmware, and interoperability with existing C codebases, Swift offers a highly productive and safe development experience.</p>
<p>Embedded Swift is still maturing, but its momentum is undeniable. With ongoing compiler work, community-driven examples, and growing interest from developers, it’s poised to play a major role in the future of embedded systems.</p>
<p>Whether you're building an IoT device, a piece of industrial equipment, or a proof-of-concept wearable, Swift can help you write safer, more expressive firmware, without giving up performance or control.</p>
<p>Swift can be especially powerful during the prototyping phase, when the primary goal is to validate functionality quickly and safely. And with its increasing support for multiple hardware platforms, it offers a strong foundation for bringing modern software development practices to the embedded world.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Robust Networking Layers in Swift with OpenAPI ]]>
                </title>
                <description>
                    <![CDATA[ What is the Problem We’re Solving? For many app developers, including me, writing the networking layer of an application is a familiar and tedious process. You write and test your first call and after that, it involves a repetitive cycle of tasks. Th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-robust-networking-layers-in-swift-with-openapi/</link>
                <guid isPermaLink="false">687fd1a603524e3b4e7b77fe</guid>
                
                    <category>
                        <![CDATA[ OpenApi ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ openapi generator ]]>
                    </category>
                
                    <category>
                        <![CDATA[ OpenAPI Specification ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SwiftUI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sravan Karuturi ]]>
                </dc:creator>
                <pubDate>Tue, 22 Jul 2025 18:00:06 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1753206547489/dce9a849-1ccd-4cb0-bca8-f879a5aadf5f.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-what-is-the-problem-were-solving"><strong>What is the Problem We’re Solving?</strong></h2>
<p>For many app developers, including me, writing the networking layer of an application is a familiar and tedious process. You write and test your first call and after that, it involves a repetitive cycle of tasks.</p>
<p>This is how it would look in the case of Swift:</p>
<ol>
<li><p>You create a <code>URLSession</code> Instance.</p>
</li>
<li><p>You create a <code>URLRequest</code> Object.</p>
</li>
<li><p>You create the <code>@Codable</code> models to match the expected input and output from the server.</p>
</li>
</ol>
<p>You do the above steps for each API endpoint you have on your backend that your app uses. Not only is this process time-consuming and not challenging for developers, it’s also error prone. </p>
<p>In the above case, if there was a minor change in the backend API – perhaps a renamed field or a new property – this would lead to the app potentially breaking. But you wouldn’t know this until you shipped it to QA or in a worse case, your consumer. This is where the OpenAPI Specification emerges as a modern, robust solution. </p>
<p>In this tutorial, you’ll learn what OpenAPI is and how it can help make your development process better. After that, we’ll implement OpenAPI by creating a small SwiftUI app and using OpenAPI methodologies to interface with the <code>JSONPlaceholder</code> API. Let’s get started.</p>
<h2 id="heading-who-is-this-guide-for"><strong>Who is This Guide For?</strong></h2>
<p>This guide is intended both for new developers looking for best practices and for experienced developers looking to implement or learn more about the OpenAPI Specification. Let’s get into it.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-openapi-and-why-should-you-care">What is OpenAPI and Why Should You Care?</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-benefits-for-swift-ios-developers">Benefits for Swift (iOS) Developers</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-a-practical-guide-to-implementing-this-solution">A Practical Guide to Implementing This Solution</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-create-a-good-openapiyaml-file-the-specification">Step 1: Create a good openapi.yaml file (the specification)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-set-up-your-project">Step 2: Set up your project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-write-a-wrapper">Step 3: Write a wrapper</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-call-the-wrapper-and-display-the-data">Step 4: Call the wrapper and display the data</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-potential-pitfalls">Potential Pitfalls</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-verbose-or-ugly-generated-code">Verbose or ugly generated code</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-large-specs-and-performance-issues">Large Specs and Performance Issues</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-unsupported-spec-features">Unsupported Spec Features</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion-embrace-spec-driven-development">Conclusion: Embrace Spec-Driven Development</a></p>
</li>
</ul>
<h2 id="heading-what-is-openapi-and-why-should-you-care"><strong>What is OpenAPI and Why Should You Care?</strong></h2>
<p>At its core, the OpenAPI Specification provides a <em>standard, language-agnostic interface</em> for describing RESTful APIs. This specification, once populated, allows both humans and computers to discover and understand the capabilities of a service without needing to access the source code or the network requests.</p>
<p>The power of OpenAPI is that it acts as a <em>formal contract between different parts of the system.</em> This contract helps both frontend and backend programmers by removing ambiguity during design process. This also has added benefit of using code generators to generate boiler-plate code both on backend and on the client ( which we will also discuss today ).</p>
<p>Traditionally when you want to create a new API in a team, either the PM, the frontend engineer, or the backend engineer takes it upon themselves to request it. Then the backend team builds it and documents it. This in turn is used by the front end team to use the API. </p>
<p><code>Some Requester → Backend Team → Documentation → Frontend Team</code></p>
<p>If you’re using OpenAPI, when someone makes a request for a new API, it is formalized into a specification after deliberations with both the frontend and the backend team. This then serves as the source of truth and is used to generate the backend and the frontend code without as much interdependence.</p>
<p><code>Some Requester → All Teams → Specification → All Teams.</code></p>
<p>This not only streamlines the process of adding new APIs, but provides a definitive source of truth for each endpoint. This also makes it so that frontend engineers and backend engineers are not misaligned about a provided parameter in the result being an <code>Int</code> or a <code>String</code> and so on. <strong>It’s all in the Spec.</strong></p>
<h3 id="heading-benefits-for-swift-ios-developers"><strong>Benefits for Swift (iOS) Developers</strong></h3>
<p>Adopting OpenAPI and <code>swift-openapi-generator</code> brings a host of tangible benefits to the Swift/App development process. It transforms how applications interact with web services in a few key ways.</p>
<h4 id="heading-reduced-development-time-and-cost">Reduced Development Time and Cost</h4>
<p>The most immediate improvement you will see is the significant reduction in boilerplate code you have to write. The generator automates the creation of what is called boilerplate code or ceremonial code. This is the repetitive logic for network requests, response handling, and data model definitions.</p>
<p>By delegating this work, developers can work on the core features of the application which leads to faster and more interesting development cycles.</p>
<h4 id="heading-compile-time-type-safety">Compile Time Type Safety</h4>
<p>This has been a major improvement for me personally. Instead of relying on the “strongly” typed keys for JSON parsing, we now work with strongly typed models. The generator creates native Swift struct and enum types directly from the schemas defined in the OpenAPI document. This brings the power of a strongly-typed system to the networking and parsing layer.</p>
<p>For example, if the return value of an API is made optional, instead of crashing at runtime, we will fail to compile at build time. This forces us to address this issue right away. </p>
<h4 id="heading-improved-collaboration-and-interoperability">Improved Collaboration and Interoperability</h4>
<p>This makes sure that all the developers are on the same page with regard to a given endpoint. And since this specification is language agnostic, it will serve as a universal language for all teams involved in the project – mobile, web and backend. </p>
<h4 id="heading-other-tooling">Other Tooling</h4>
<p>Once you have a specification, you can use that to power a wide variety of tools. You can generate interactive documentation, create mock servers for frontend development, and run automated tests. </p>
<p>Alright hopefully you’re sold – so now how do you implement this into your project?</p>
<h2 id="heading-a-practical-guide-to-implementing-this-solution">A Practical Guide to Implementing This Solution</h2>
<p>We’ll now take a look at a practical example so you can understand how you can implement this in a project. This involves:</p>
<ul>
<li><p>Creating an openapi.yaml file to describe the API specification.</p>
</li>
<li><p>Configuring and integrating <code>swift-openapi-generator</code> into a SwiftUI application. </p>
</li>
<li><p>Prototyping an app that fetches and displays a list of posts from the <a target="_blank" href="https://jsonplaceholder.typicode.com/">https://jsonplaceholder.typicode.com/</a> </p>
</li>
</ul>
<p>To follow along, you will need Xcode installed and a basic understanding of Swift programming and SwiftUI for App development.</p>
<h3 id="heading-step-1-create-a-good-openapiyaml-file-the-specification">Step 1: Create a good openapi.yaml file (the specification)</h3>
<p>The quality of a specification is really important because it directly determines the quality of the code produced by <code>swift-openapi-generator</code>. If you don’t have a good specification, you might run into several issues that developers often complain about, like confusing and long method names.</p>
<p>For example, it might generate something like <code>get_all_my_meal_recipes_hyphen_detailed</code>. This might happen because the generator is forced to create a new name based on the API path if the identifier is not provided in the spec. So, instead of dealing with these issues one after the other, we will create a <em>good clear specification</em> to start with.</p>
<p>Since we’re using the <code>jsonplaceholder</code> as our backend server, we are limited by what tweaks we can make – but it is a fantastic project that lets us mimic a backend server.</p>
<p>In general, an OpenAPI.yaml file contains:</p>
<ol>
<li><p>OpenAPI Info and servers – This will provide the metadata about the API like the OpenAPI version, which server to point to for calls, and so on. </p>
</li>
<li><p>Paths – This will provide the available endpoints. In our case, it can contain /posts as one of them. We also will have to mention the kind of endpoint (get, post, put, and so on)</p>
</li>
<li><p>OperationID – This field instructs the generator to create a clear method with this name. </p>
</li>
<li><p>Responses – This defines the possible outcomes of an API call. We will specify the structure of a successful 200 OK response or any other errors here. </p>
</li>
<li><p>Components / Schemas – This defines all the reusable components and data models. If we have a Post schema definer here, the generator will use this to create a Post struct in Swift to match this. </p>
</li>
</ol>
<p>Keeping in mind all these elements, I compiled a yaml file for us to use for this tutorial:</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># openapi.yaml</span>
<span class="hljs-attr">openapi:</span> <span class="hljs-string">"3.0.3"</span>
<span class="hljs-attr">info:</span>
  <span class="hljs-attr">title:</span> <span class="hljs-string">"JSONPlaceholder API"</span>
  <span class="hljs-attr">version:</span> <span class="hljs-string">"1.0.0"</span>
<span class="hljs-attr">servers:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">url:</span> <span class="hljs-string">"https://jsonplaceholder.typicode.com"</span>
<span class="hljs-attr">paths:</span>
  <span class="hljs-string">/posts:</span>
    <span class="hljs-attr">get:</span>
      <span class="hljs-attr">summary:</span> <span class="hljs-string">"Get all posts"</span>
      <span class="hljs-attr">operationId:</span> <span class="hljs-string">"getPosts"</span>
      <span class="hljs-attr">responses:</span>
        <span class="hljs-attr">"200":</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">"A list of posts"</span>
          <span class="hljs-attr">content:</span>
            <span class="hljs-attr">application/json:</span>
              <span class="hljs-attr">schema:</span>
                <span class="hljs-attr">type:</span> <span class="hljs-string">array</span>
                <span class="hljs-attr">items:</span>
                  <span class="hljs-string">$ref:</span> <span class="hljs-string">"#/components/schemas/Post"</span>
<span class="hljs-attr">components:</span>
  <span class="hljs-attr">schemas:</span>
    <span class="hljs-attr">Post:</span>
      <span class="hljs-attr">type:</span> <span class="hljs-string">object</span>
      <span class="hljs-attr">required:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">userId</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">id</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">title</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">body</span>
      <span class="hljs-attr">properties:</span>
        <span class="hljs-attr">userId:</span>
          <span class="hljs-attr">type:</span> <span class="hljs-string">integer</span>
        <span class="hljs-attr">id:</span>
          <span class="hljs-attr">type:</span> <span class="hljs-string">integer</span>
        <span class="hljs-attr">title:</span>
          <span class="hljs-attr">type:</span> <span class="hljs-string">string</span>
        <span class="hljs-attr">body:</span>
          <span class="hljs-attr">type:</span> <span class="hljs-string">string</span>
</code></pre>
<p>The first line here, <code>openapi: “3.0.3”</code>, just tells the generators and parsers that we are using version <code>3.0.3</code>. </p>
<p>Next, we have some more metadata – the name and version of the API. We also have the server we are calling with our APIs.</p>
<p>After defining this metadata, we now define our endpoints. For the sake of this example, let’s assume that we only have one endpoint to call to get posts. We represent this by saying <code>/posts</code> under paths. We then specify which kind it is by specifying <code>get:</code>.</p>
<p>We give a short description of what it does in the <code>summary</code> and then specify an <code>operationId</code> which is what we this function will be called in our generated code. We also specify exactly what structure the response will have, that is, a JSON of an array of <code>Posts</code>.</p>
<p>We then list any components we have across our APIs like the <code>Post</code>. Note that we are using the <code>Post</code> schema in the return response structure before we define it further down. The schemas in components will determine the Model structs we will generate using this yaml file.</p>
<h3 id="heading-step-2-set-up-your-project">Step 2: Set up your project</h3>
<p>Create a new SwiftUI project. For the purpose of this tutorial, we’ll use an iOS app – but you can do this with any app. Select Swift as the language and SwiftUI for the interface.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753047209636/75cad7d3-f403-4285-8209-fd2bb65418e5.png" alt="App Creation Screen" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753047246793/3491aa5d-c35c-4157-adf2-789fe5e9cd96.png" alt="Basic SwiftUI App after it's created" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
<p>Add the <code>openapi.yaml</code> file we just created to this project. (You can also create this file in Xcode and copy, paste from the script above.)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753047290178/fc31b759-b1c4-4b48-b58b-d90109614cd0.png" alt="Adding the openapi.yaml file to our project" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
<p>Now, add the following swift packages to the project. (<strong>Note: Please read the entire section about adding packages before you proceed.</strong>)</p>
<ol>
<li><p>Swift OpenAPI Generator – <a target="_blank" href="https://github.com/apple/swift-openapi-generator">https://github.com/apple/swift-openapi-generator</a> – The Core Generator Plugin.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753047376776/b1d7b2d0-9b1f-45c8-8c74-4395a4c80dd9.png" alt="Adding Swift OpenAPI Generator to our Project" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753047411622/c6eca0c0-538e-40b5-a9b0-9fa044b60694.png" alt="Making sure that no targets are selected for the OpenAPIGenerator" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
</li>
<li><p>Swift OpenAPI Runtime – <a target="_blank" href="https://github.com/apple/swift-openapi-runtime">https://github.com/apple/swift-openapi-runtime</a> – This contains the common types and protocols used by the code generated by the generator plugin.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753047457532/846ec488-cfed-4ca5-811b-c38dba0aaf30.png" alt="Adding OpenAPIRuntime to our project" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
</li>
<li><p>Swift OpenAPI URLSession – <a target="_blank" href="https://github.com/apple/swift-openapi-urlsession">https://github.com/apple/swift-openapi-urlsession</a> – This is a transport layer that allows the generated code to use the Apple URLSession to make network requests. </p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753047476699/9556047e-cc33-44b4-9980-0c692d4c1d01.png" alt="Adding OpenAPIURLSession to our Project" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
</li>
</ol>
<p>One major caveat to note here when adding these packages is that <strong>The Swift OpenAPI Generator</strong> should <strong>not</strong> be added to your project target. This is because we’re only using this to generate the code, but we’re not using it in the app.</p>
<p>If you get this error: <code>swift-openapi-generator/Sources/_OpenAPIGeneratorCore/PlatformChecks.swift:21:5 _OpenAPIGeneratorCore is only to be used by swift-openapi-generator itself—your target should not link this library or the command line tool directly.</code> – then you made this mistake.</p>
<p>The easiest way to fix this is removing the package and adding it again. Or you can go to <code>Project → Target → Build Phases → Link Binary with Libraries → Remove Swift OpenAPI Generator</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753048265985/100428a4-e46a-4aa1-8fcf-4c74e26ffed6.png" alt="Where to check if you encounter that error" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
<p>Now that we added these generator and runtime plugins, we need to give the generator some instructions on what to generate. You can do this with an <code>openapi-generator-config.yaml</code> file. For our project, use the following file. It’s really simple:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">generate:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">types</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">client</span>
</code></pre>
<p>This tells our generator to generate the <strong>types</strong> – the swift structs, enums, and so on from the schema section of the file, and the <strong>client</strong> – the main class which interacts with the networking logic.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753048237863/963d6bc0-a368-427b-add3-75dcf4bd3edf.png" alt="openapi-generator-config.yaml file" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
<p>Save this into an <code>openapi-generator-config.yaml</code> file as shown.</p>
<p>And finally, we want the generator to run whenever we want to build this application/target. We can specify this in the Build Phases tab of the target. Under the “ Target → Build Phases → Run Build Tool Plug-ins” , add the OpenAPIGenerator Plugin.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753048334094/24e20adc-c6e0-4d66-965b-19d476a5ffd3.png" alt="Adding the generator in the build phase" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
<p>The first time the project is built after setting this, Xcode will display a security dialog. This will let us “Trust and Enable” for this plugin. It’s a one time confirmation that gives this plugin the permission required to run during the build process.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753048374405/6ff51ff4-d33a-4920-b95f-9fda0ee0aef4.png" alt="Trust and Enable security dialog for the generator" class="image--center mx-auto" width="1512" height="1012" loading="lazy"></p>
<p>As soon as you build the second time after giving these permissions, you will generate the files. You might not see any changes in the Xcode window itself. But if you’re curious to see the result, go to this folder. </p>
<p><code>DerivedData →  &lt;ProjectName&gt;*identifier → Build → intermediates.noindex → BuildToolPluginIntermediates → &lt;TargetName&gt;.output → &lt;TargetName&gt; → OpenAPIGenerator → GeneratedSources</code></p>
<p>More on derived data folder here: <a target="_blank" href="https://gayeugur.medium.com/derived-data-2e9468c6da9b">https://gayeugur.medium.com/derived-data-2e9468c6da9b</a> if you’re curious.</p>
<p>Keep in mind that this location might vary based on Xcode version, OpenAPI version, and your project settings. But you don’t need to worry about the file location.</p>
<p>You will see three files called Client.swift, Types.swift, and Server.swift.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753048508703/8fcec6bf-ad86-47de-b57c-7dca22256e06.png" alt="Generated Files" class="image--center mx-auto" width="1148" height="710" loading="lazy"></p>
<p>These are the files that the our generator created and populated with the types and functions we need.</p>
<p>In the next section, we discuss how to use these files to make calls to the server.</p>
<h3 id="heading-step-3-write-a-wrapper">Step 3: Write a wrapper</h3>
<p>While it’s certainly possible to make the calls to server using just the generated code (<code>Client</code>) type throughout our application, a more maintainable approach is to use a wrapper around these types. This will provide a stable, clean interface for the rest our our app to use, and it decouples feature code from the generated code.</p>
<p>I can hear you thinking: “Wait a second. Isn’t the entire purpose of generating this code to avoid this boilerplate abstraction?”</p>
<p>While it adds some abstraction on top of the generated code, it’s valuable to have this for number of reasons. Here are but a few of them:</p>
<ol>
<li><p>Better naming. The generated <code>Post</code> struct right now will be called <code>Components.Schemas.Post</code>.</p>
</li>
<li><p>If you ever want to move away from the generator, an abstraction is really helpful.</p>
</li>
<li><p>If you want to Mock this server call, you can do this via the abstraction.</p>
</li>
<li><p>UI Optimization. You might want to flatten the structure of a model to reduce the number of computed variables in there, and so on.</p>
</li>
</ol>
<p>So, we want to wrap this around a file called <code>WebService.swift</code>:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// WebService.swift</span>
<span class="hljs-keyword">import</span> Foundation
<span class="hljs-keyword">import</span> OpenAPIURLSession

<span class="hljs-comment">// A clean, app-specific Post model.</span>
<span class="hljs-comment">// This decouples views from the generated types.</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">AppPost</span>: <span class="hljs-title">Identifiable</span>, <span class="hljs-title">Codable</span> </span>{
    <span class="hljs-keyword">let</span> id: <span class="hljs-type">Int</span>
    <span class="hljs-keyword">let</span> title: <span class="hljs-type">String</span>
    <span class="hljs-keyword">let</span> body: <span class="hljs-type">String</span>
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WebService</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">let</span> client: <span class="hljs-type">Client</span>

    <span class="hljs-keyword">init</span>() {
        <span class="hljs-comment">// The server URL and transport are from the generated code.</span>
        <span class="hljs-comment">// `Servers.Server1.url()` corresponds to the first URL in the `servers` array of the spec.</span>
        <span class="hljs-keyword">self</span>.client = <span class="hljs-type">Client</span>(
            serverURL: <span class="hljs-keyword">try</span>! <span class="hljs-type">Servers</span>.<span class="hljs-type">Server1</span>.url(),
            transport: <span class="hljs-type">URLSessionTransport</span>()
        )
    }

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getPosts</span><span class="hljs-params">()</span></span> async <span class="hljs-keyword">throws</span> -&gt; [<span class="hljs-type">AppPost</span>] {
        <span class="hljs-comment">// Call the generated method, which was named using `operationId`.</span>
        <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">try</span> await client.getPosts(.<span class="hljs-keyword">init</span>())

        <span class="hljs-comment">// The generated response is a type-safe enum covering all documented status codes.</span>
        <span class="hljs-keyword">switch</span> response {
        <span class="hljs-keyword">case</span>.ok(<span class="hljs-keyword">let</span> okResponse):
            <span class="hljs-comment">// The body is also a type-safe enum for different content types.</span>
            <span class="hljs-keyword">switch</span> okResponse.body {
            <span class="hljs-keyword">case</span>.json(<span class="hljs-keyword">let</span> posts):
                <span class="hljs-comment">// Map the generated `Components.Schemas.Post` to our clean `AppPost` model.</span>
                <span class="hljs-keyword">return</span> posts.<span class="hljs-built_in">map</span> { post <span class="hljs-keyword">in</span>
                    <span class="hljs-type">AppPost</span>(id: post.id, title: post.title, body: post.body)
                }
            }
        <span class="hljs-comment">// The generator forces the handling of other documented responses.</span>
        <span class="hljs-comment">// Our simple spec only has a 200, so any other response is undocumented.</span>
        <span class="hljs-keyword">case</span>.undocumented(statusCode: <span class="hljs-keyword">let</span> statusCode, <span class="hljs-number">_</span>):
            <span class="hljs-keyword">throw</span> <span class="hljs-type">URLError</span>(.badServerResponse, userInfo: [<span class="hljs-string">"statusCode"</span>: statusCode])
        }
    }
}
</code></pre>
<p>Let’s go through this file to understand what we’re doing.</p>
<p>First, we import <code>OpenAPIUrlSession</code> along with <code>Foundation</code>. This allows us to call the server, get a response and parse that response.</p>
<p>Next, we define the new <code>AppPost</code> struct. This is meant to be the representation of a <code>Post</code> in the App. In the generated <code>Types.Swift</code> file, we have the generated <code>Post</code> structure. This is defined as:</p>
<pre><code class="lang-swift"><span class="hljs-comment">/// - Remark: Generated from `#/components/schemas/Post`.</span>
        <span class="hljs-keyword">internal</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Post</span>: <span class="hljs-title">Codable</span>, <span class="hljs-title">Hashable</span>, <span class="hljs-title">Sendable</span> </span>{
            <span class="hljs-comment">/// - Remark: Generated from `#/components/schemas/Post/userId`.</span>
            <span class="hljs-keyword">internal</span> <span class="hljs-keyword">var</span> userId: <span class="hljs-type">Swift</span>.<span class="hljs-type">Int</span>
            <span class="hljs-comment">/// - Remark: Generated from `#/components/schemas/Post/id`.</span>
            <span class="hljs-keyword">internal</span> <span class="hljs-keyword">var</span> id: <span class="hljs-type">Swift</span>.<span class="hljs-type">Int</span>
            <span class="hljs-comment">/// - Remark: Generated from `#/components/schemas/Post/title`.</span>
            <span class="hljs-keyword">internal</span> <span class="hljs-keyword">var</span> title: <span class="hljs-type">Swift</span>.<span class="hljs-type">String</span>
            <span class="hljs-comment">/// - Remark: Generated from `#/components/schemas/Post/body`.</span>
            <span class="hljs-keyword">internal</span> <span class="hljs-keyword">var</span> body: <span class="hljs-type">Swift</span>.<span class="hljs-type">String</span>
            <span class="hljs-comment">/// Creates a new `Post`.</span>
            <span class="hljs-comment">///</span>
            <span class="hljs-comment">/// - Parameters:</span>
            <span class="hljs-comment">///   - userId:</span>
            <span class="hljs-comment">///   - id:</span>
            <span class="hljs-comment">///   - title:</span>
            <span class="hljs-comment">///   - body:</span>
            <span class="hljs-keyword">internal</span> <span class="hljs-keyword">init</span>(
                userId: <span class="hljs-type">Swift</span>.<span class="hljs-type">Int</span>,
                id: <span class="hljs-type">Swift</span>.<span class="hljs-type">Int</span>,
                title: <span class="hljs-type">Swift</span>.<span class="hljs-type">String</span>,
                body: <span class="hljs-type">Swift</span>.<span class="hljs-type">String</span>
            ) {
                <span class="hljs-keyword">self</span>.userId = userId
                <span class="hljs-keyword">self</span>.id = id
                <span class="hljs-keyword">self</span>.title = title
                <span class="hljs-keyword">self</span>.body = body
            }
            <span class="hljs-keyword">internal</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">CodingKeys</span>: <span class="hljs-title">String</span>, <span class="hljs-title">CodingKey</span> </span>{
                <span class="hljs-keyword">case</span> userId
                <span class="hljs-keyword">case</span> id
                <span class="hljs-keyword">case</span> title
                <span class="hljs-keyword">case</span> body
            }
        }
</code></pre>
<p>As you can see, our <code>AppPost</code> struct is different from this generated type. We omit the <code>userId</code> since we do not care about it (at least for now).</p>
<p>Back to the <code>WebService</code> class, we see a <code>client</code> attribute. This is a generated type variable that will let us interact with the servers. In the initializer of the <code>WebService</code> class, we create a new <code>Client</code> using the first server URL we specified in the schema and use the <code>URLSessionTransport</code> object for making these calls.</p>
<p>We then define our methods. In this case, our <code>getPosts()</code> function which returns <code>[AppPost]</code> array.</p>
<p><code>let response = try await client.getPosts(.init())</code> will call the function <code>getPosts()</code> on the <code>Client</code> object. The <code>Client.getPosts()</code> function here takes in an input struct called <code>Operations.getPosts.Input</code> which is initialized by the <code>.init()</code> passed here.</p>
<p>This generated response is a type-safe enum covering all documented codes. (Currently only <code>200</code> in our yaml file). So, we use a simple switch to look at both these cases and further use more switch statements to get the proper response. You can see how much easier this is than to parse the response manually.</p>
<p>Once we get the <code>Components.Schemas.Post</code> response, we map and convert it into <code>[AppPost]</code> array and return it.</p>
<p>Now, let’s use this wrapper to display data in our app.</p>
<h3 id="heading-step-4-call-the-wrapper-and-display-the-data">Step 4: Call the wrapper and display the data</h3>
<p>We’re at the final step now. We’ll use the wrapper we created to display the fetched posts. We’ll also use a state variable to store our <code>AppPost</code> array in our <code>ContentView</code> view. We’ll then call <code>getPosts()</code> when the view is first displayed to the user.</p>
<pre><code class="lang-swift"><span class="hljs-comment">// ContentView.swift</span>
<span class="hljs-keyword">import</span> SwiftUI

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">ContentView</span>: <span class="hljs-title">View</span> </span>{
    @<span class="hljs-type">State</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> posts: [<span class="hljs-type">AppPost</span>] = []
    @<span class="hljs-type">State</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> errorMessage: <span class="hljs-type">String?</span>

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">let</span> webService = <span class="hljs-type">WebService</span>()

    <span class="hljs-keyword">var</span> body: some <span class="hljs-type">View</span> {
        <span class="hljs-type">NavigationStack</span> {
            <span class="hljs-type">List</span>(posts) { post <span class="hljs-keyword">in</span>
                <span class="hljs-type">VStack</span>(alignment:.leading, spacing: <span class="hljs-number">8</span>) {
                    <span class="hljs-type">Text</span>(post.title)
                       .font(.headline)
                    <span class="hljs-type">Text</span>(post.body)
                       .font(.subheadline)
                       .foregroundColor(.secondary)
                }
               .padding(.vertical, <span class="hljs-number">4</span>)
            }
           .navigationTitle(<span class="hljs-string">"Posts"</span>)
           .task {
                await loadPosts()
            }
           .overlay {
                <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> errorMessage {
                    <span class="hljs-type">ContentUnavailableView</span>(<span class="hljs-string">"Error"</span>, systemImage: <span class="hljs-string">"xmark.octagon"</span>, description: <span class="hljs-type">Text</span>(errorMessage))
                } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> posts.isEmpty {
                    <span class="hljs-type">ProgressView</span>()
                }
            }
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">loadPosts</span><span class="hljs-params">()</span></span> async {
        <span class="hljs-keyword">self</span>.errorMessage = <span class="hljs-literal">nil</span>
        <span class="hljs-keyword">do</span> {
            <span class="hljs-keyword">self</span>.posts = <span class="hljs-keyword">try</span> await webService.getPosts()
        } <span class="hljs-keyword">catch</span> {
            <span class="hljs-keyword">self</span>.errorMessage = error.localizedDescription
        }
    }
}

#<span class="hljs-type">Preview</span> {
    <span class="hljs-type">ContentView</span>()
}
</code></pre>
<p>You can see the dummy posts in the Preview. As you can see, all we had to do was call the <code>webService.getPosts()</code> to populate the variable.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753053957409/b89d50e8-ab73-4484-beda-3a328a575144.png" alt="Simulator Run of the app showing the fetched posts" class="image--center mx-auto" width="1179" height="2556" loading="lazy"></p>
<p>You might be thinking that this is a lot of setup for a simple struct like <code>Post</code> for which we had to create a wrapper called <code>AppPost</code> anyway. But if you had ten types like this and twenty endpoints to call? You wouldn’t have to deal with a lot of repetitive, error-prone code.</p>
<h2 id="heading-potential-pitfalls">Potential Pitfalls</h2>
<p>Unfortunately, no process is perfect. You might still face a lot of issues with generated code and this method. I’ve listed some of them here and how to deal with them.</p>
<h3 id="heading-verbose-or-ugly-generated-code">Verbose or ugly generated code</h3>
<p>If you have very verbose or ugly generated code, the problem is almost always the missing <code>operationId</code> for an API path. If you don’t specify one, the generator must create a name from the path and the HTTP method with results in long unwieldy names. Adding a clear <code>operationId</code> will mitigate this issue.</p>
<h3 id="heading-large-specs-and-performance-issues">Large Specs and Performance Issues</h3>
<p>If you have a very large Spec file, generating a client for this entire specification can significantly increase the compile time. It can also result in absolutely massive <code>Types.swift</code> and <code>Client.swift</code> files.</p>
<p>There is a filter option in the <code>openapi-generator-config.yaml</code> file that will allow the generator to include only parts of the spec that are relevant to the application to improve build times and so on. But if you want everything in an API that has hundreds of endpoints, the only way to reduce compile times is to avoid regenerating this every time and decouple this step from the regular build process.</p>
<h3 id="heading-unsupported-spec-features">Unsupported Spec Features</h3>
<p>While the swift package, <code>swift-openapi-generator</code>, is robust, it does not support all the features included in the specification. I had issues with some features of the newer spec version ( <code>3.1.1</code> and had to downgrade to <code>3.0.3</code> to make it work well ).</p>
<p>There are also known issues like lack of support for certain types of recursive schemas. Sometimes, the generator errors out and fails and some other times, it generates incomplete types – which can result in a few hours of debugging (I speak from experience).</p>
<p>In any case, knowing the limits of this generator can be helpful in avoiding issues it might cause. Also keep in mind that it is always getting better thanks to its open source nature.</p>
<h2 id="heading-conclusion-embrace-spec-driven-development">Conclusion: Embrace Spec-Driven Development</h2>
<p>In this guide, you navigated the journey of adopting <code>swift-openapi-generator</code> – from understanding the power of API contracts to building a functional SwiftUI app. You also learned about the real life challenges of this process. While there is an initial learning curve, the benefits of this approach are profound.</p>
<p>The core tenet of this approach is to foster more disciplined and more robust method for building applications. By making the OpenAPI document the single source of truth, you make sure that both the frontend and backend are perfectly in sync in perpetuity.</p>
<p>Using this approach also results in more type-safe, maintainable code. The result is less time spent on writing boilerplate and debugging random integration errors and more time spent creating the app itself.</p>
<p>For developers ready to explore further, please checkout the official <code>swift-openapi-generator</code> repository on Github here: <a target="_blank" href="https://github.com/apple/swift-openapi-generator">https://github.com/apple/swift-openapi-generator</a>.</p>
<p>You can follow me on <a target="_blank" href="https://github.com/sravankaruturi">GitHub</a> and <a target="_blank" href="https://hashnode.com/@sravankaruturi">Hashnode</a> for my other posts and projects.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn the Swift Programming Language ]]>
                </title>
                <description>
                    <![CDATA[ Swift is popular programming language that is often used for creating iOS apps.  We just released a full course on the freeCodeCamp.org YouTube channel that will teach you the Swift programming language. Vandad Nahavandipoor teaches this course. He c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-the-swift-programming-language/</link>
                <guid isPermaLink="false">66b2054beea9870582e16ca1</guid>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Wed, 07 Dec 2022 16:51:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/12/swift.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Swift is popular programming language that is often used for creating iOS apps. </p>
<p>We just released a full course on the freeCodeCamp.org YouTube channel that will teach you the Swift programming language.</p>
<p>Vandad Nahavandipoor teaches this course. He currently works as a lead iOS developer and he has created many other popular courses.</p>
<p>In this course you will learn every modern aspect of Swift as a programming language including, variables, constants, functions, structures, classes, protocols. extensions, asynchronous programming, generics and much more. This course will lay the foundation for learning Swift for those who are not familiar with Swift already.</p>
<p>Here are the sections in this course:</p>
<ul>
<li>Variables</li>
<li>Operators</li>
<li>If and else</li>
<li>Functions</li>
<li>Closures</li>
<li>Structures</li>
<li>Enumerations</li>
<li>Classes</li>
<li>Protocols</li>
<li>Extensions</li>
<li>Generics</li>
<li>Optionals</li>
<li>Error Handling</li>
<li>Collections</li>
<li>Equality and Hashing</li>
<li>Custom Operators</li>
<li>Asynchronous Programming</li>
</ul>
<p>Watch the full course <a target="_blank" href="https://youtu.be/8Xg7E9shq0U">on the freeCodeCamp.org YouTube channel</a> (7-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/8Xg7E9shq0U" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Swift Handbook – Learn Swift for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ Introduction to Swift The Swift programming language was created by Apple in 2014. It's the official language that works with the whole Apple Operating Systems lineup: iOS, iPadOS, watchOS, macOS, and tvOS. Swift is an open source, general purpose, c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-swift-handbook/</link>
                <guid isPermaLink="false">66bb5ac25a83db22bea98450</guid>
                
                    <category>
                        <![CDATA[ Apple ]]>
                    </category>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Flavio Copes ]]>
                </dc:creator>
                <pubDate>Mon, 24 Oct 2022 21:04:27 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/pexels-quang-nguyen-vinh-6131283.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-introduction-to-swift">Introduction to Swift</h2>
<p>The Swift programming language was created by Apple in 2014. It's the official language that works with the whole Apple Operating Systems lineup: iOS, iPadOS, watchOS, macOS, and tvOS.</p>
<p>Swift is an open source, general purpose, compiled programming language that's statically typed.</p>
<p>Every value has a type assigned. The type of a value is always checked when used as an argument or returned, at compile time. If there is a mismatch, the program will not compile.</p>
<p>Swift's compiler is LLVM, and it is included within Xcode, the standard IDE you use for Apple software development.</p>
<p>Swift is a modern programming language that was designed to "fit" in an ecosystem that was previously designed for a different programming language called Objective-C.</p>
<p>Most of the software running on the iPhone and Mac today is based on Objective-C code, even for official Apple apps. But Swift usage is gaining traction year after year. While Objective-C will be used for years to maintain and improve existing apps, new applications are likely going to be created with Swift.</p>
<p>Before Apple introduced Swift, Objective-C was heavily developed to introduce new capabilities and features. But in the recent years this effort has decreased a lot in favor of Swift development.</p>
<p>This does not mean Objective-C is dead or not worth learning: Objective-C is still an essential tool for any Apple developer.</p>
<p>That said, I am not going to cover Objective-C here, because we're focusing on Swift – the present and future of the Apple platform.</p>
<p>In just 6 years, Swift has gone through 5 major versions, and we're now (at the time of writing) at version 5.</p>
<p>Swift is famously Apple's products language, but it is not an Apple-only language. You can use it on several other platforms. </p>
<p>It is open source, so porting the language to other platforms does not require any permission or licensing, and you can find Swift projects to create Web servers and APIs (<a target="_blank" href="https://github.com/vapor/vapor">https://github.com/vapor/vapor</a>) as well as projects to interact with microcontrollers.</p>
<p>Swift is a general-purpose language, built with modern concepts, and it has a bright future.</p>
<h2 id="heading-what-well-cover-here">What We'll Cover Here</h2>
<p>The goal of this book is to get you up and running with Swift, starting from zero.</p>
<p>If you have a Mac or an iPad, I recommend you to download the Playgrounds application made by Apple from the App Store. </p>
<p>This app lets you run snippets of Swift code without having to create a full app first. It's a very handy way to test your code, not just when you start learning, but whenever you need to try some code.</p>
<p>It also contains a series of awesome examples and tutorials to expand your Swift and iOS knowledge.</p>
<p>Note: <a target="_blank" href="https://thevalleyofcode.com/download/swift/">You can get a PDF and ePub version of this Swift Beginner's Handbook</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-introduction-to-swift">Introduction to Swift</a></li>
<li><a class="post-section-overview" href="#heading-variables-in-swift">Variables in Swift</a></li>
<li><a class="post-section-overview" href="#heading-objects-in-swift">Objects in Swift</a></li>
<li><a class="post-section-overview" href="#heading-operators-in-swift">Operators in Swift</a></li>
<li><a class="post-section-overview" href="#heading-conditionals-in-swift">Conditionals in Swift</a></li>
<li><a class="post-section-overview" href="#heading-loops-in-swift">Loops in Swift</a></li>
<li><a class="post-section-overview" href="#heading-how-to-write-comments-in-swift">How to Write Comments in Swift</a></li>
<li><a class="post-section-overview" href="#heading-semicolons-in-swift">Semicolons in Swift</a></li>
<li><a class="post-section-overview" href="#heading-numbers-in-swift">Numbers in Swift</a></li>
<li><a class="post-section-overview" href="#heading-strings-in-swift">Strings in Swift</a></li>
<li><a class="post-section-overview" href="#heading-booleans-in-swift">Booleans in Swift</a></li>
<li><a class="post-section-overview" href="#heading-arrays-in-swift">Arrays in Swift</a></li>
<li><a class="post-section-overview" href="#heading-sets-in-swift">Sets in Swift</a></li>
<li><a class="post-section-overview" href="#heading-dictionaries-in-swift">Dictionaries in Swift</a></li>
<li><a class="post-section-overview" href="#heading-tuples-in-swift">Tuples in Swift</a></li>
<li><a class="post-section-overview" href="#heading-optionals-and-nil-in-swift">Optionals and <code>nil</code> in Swift</a> </li>
<li><a class="post-section-overview" href="#heading-enumerations-in-swift">Enumerations in Swift</a></li>
<li><a class="post-section-overview" href="#heading-structures-in-swift">Structures in Swift</a></li>
<li><a class="post-section-overview" href="#heading-classes-in-swift">Classes in Swift</a></li>
<li><a class="post-section-overview" href="#heading-functions-in-swift">Functions in Swift</a></li>
<li><a class="post-section-overview" href="#heading-protocols-in-swift">Protocols in Swift</a></li>
<li><a class="post-section-overview" href="#heading-where-to-go-from-here">Where to Go From Here</a></li>
</ul>
<h2 id="heading-variables-in-swift">Variables in Swift</h2>
<p>Variables let us assign a value to a label. We define them using the <code>var</code> keyword:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> name = <span class="hljs-string">"Roger"</span>
<span class="hljs-keyword">var</span> age = <span class="hljs-number">8</span>
</code></pre>
<p>Once a variable is defined, we can change its value:</p>
<pre><code class="lang-swift">age = <span class="hljs-number">9</span>
</code></pre>
<p>Variables that you do not want to change can be defined as constants, using the <code>let</code> keyword:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> name = <span class="hljs-string">"Roger"</span>
<span class="hljs-keyword">let</span> age = <span class="hljs-number">8</span>
</code></pre>
<p>Changing the value of a constant is forbidden.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2020-11-01-at-07.51.48.png" alt="Image" width="600" height="400" loading="lazy">
<em>You can't change the value of a constant or you'll get this error</em></p>
<p>When you define a variable and you assign it a value, Swift implicitly infers the type of it.</p>
<p><code>8</code> is an <code>Int</code> value.</p>
<p><code>"Roger"</code> is a <code>String</code> value.</p>
<p>A decimal number like <code>3.14</code> is a <code>Double</code> value.</p>
<p>You can also specify the type at initialization time:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> age: <span class="hljs-type">Int</span> = <span class="hljs-number">8</span>
</code></pre>
<p>But it's typical to let Swift infer it, and it's mostly done when you declare a variable without initializing it.</p>
<p>You can declare a constant, and initialize it later:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> age : <span class="hljs-type">Int</span>

age = <span class="hljs-number">8</span>
</code></pre>
<p>Once a variable is defined, it is bound to that type. You cannot assign to it a different type, unless you explicitly convert it.</p>
<p>You can't do this:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> age = <span class="hljs-number">8</span>
age = <span class="hljs-string">"nine"</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2020-11-01-at-07.54.25.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cannot assign value of type 'String' to type 'Int' error</em></p>
<p><code>Int</code> and <code>String</code> are just two of the built-in data types provided by Swift.</p>
<h2 id="heading-objects-in-swift">Objects in Swift</h2>
<p>In Swift, everything is an object. Even the <code>8</code> value we assigned to the <code>age</code> variable is an object.</p>
<p>In some languages, objects are a special type. But in Swift, everything is an object and this leads to one particular feature: every value can <em>receive messages</em>.</p>
<p>Each type can have multiple functions associated to it, which we call <strong>methods</strong>.</p>
<p>For example, talking about the <code>8</code> number value, we can call its <code>isMultiple</code> method, to check if the number is a multiple of another number:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2020-11-01-at-14.43.49.png" alt="Image" width="600" height="400" loading="lazy">
<em><code>isMultiple</code> method</em></p>
<p>A String value has another set of methods.</p>
<p>A type also has instance variables. For example the String type has the instance variable <code>count</code>, which gives you the number of characters in a string:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2020-11-01-at-14.45.39.png" alt="Image" width="600" height="400" loading="lazy">
<em>instance variable <code>count</code></em></p>
<p>Swift has 3 different <strong>object types</strong>, which we'll see more in details later on: <strong>classes</strong>, <strong>structs</strong> and <strong>enums</strong>.</p>
<p>Those are very different, but they have one thing in common: to object type, we can <strong>add methods</strong>, and to any value, of any object type, we can <strong>send messages</strong>.</p>
<h2 id="heading-operators-in-swift">Operators in Swift</h2>
<p>We can use a wide set of operators to operate on values.</p>
<p>We can divide operators in many categories. The first is the number of targets: 1 for <strong>unary operators</strong>, 2 for <strong>binary operators</strong> or 3 for the one and only <strong>ternary operator</strong>.</p>
<p>Then we can divide operators based on the kind of operation they perform:</p>
<ul>
<li>assignment operator</li>
<li>arithmetic operators</li>
<li>compound assignment operators</li>
<li>comparison operators</li>
<li>range operators</li>
<li>logical operators</li>
</ul>
<p>plus some more advanced ones, including nil-coalescing, ternary conditional, overflow, bitwise and pointwise operators.</p>
<p>Note: Swift allows you to create your own operators and define how operators work on your types you define.</p>
<h3 id="heading-assignment-operator-in-swift">Assignment operator in Swift</h3>
<p>You use the assignment operator to assign a value to a variable:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> age = <span class="hljs-number">8</span>
</code></pre>
<p>Or to assign a variable value to another variable:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> age = <span class="hljs-number">8</span>
<span class="hljs-keyword">var</span> another = age
</code></pre>
<h3 id="heading-arithmetic-operators-in-swift">Arithmetic operators in Swift</h3>
<p>Swift has a number of binary arithmetic operators: <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code> (division), <code>%</code> (remainder):</p>
<pre><code class="lang-swift"><span class="hljs-number">1</span> + <span class="hljs-number">1</span> <span class="hljs-comment">//2</span>
<span class="hljs-number">2</span> - <span class="hljs-number">1</span> <span class="hljs-comment">//1</span>
<span class="hljs-number">2</span> * <span class="hljs-number">2</span> <span class="hljs-comment">//4</span>
<span class="hljs-number">4</span> / <span class="hljs-number">2</span> <span class="hljs-comment">//2</span>
<span class="hljs-number">4</span> % <span class="hljs-number">3</span> <span class="hljs-comment">//1</span>
<span class="hljs-number">4</span> % <span class="hljs-number">2</span> <span class="hljs-comment">//0</span>
</code></pre>
<p><code>-</code> also works as a unary minus operator:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> hotTemperature = <span class="hljs-number">20</span>
<span class="hljs-keyword">let</span> freezingTemperature = -<span class="hljs-number">20</span>
</code></pre>
<p>You can also use <code>+</code> to concatenate String values:</p>
<pre><code class="lang-swift"><span class="hljs-string">"Roger"</span> + <span class="hljs-string">" is a good dog"</span>
</code></pre>
<h3 id="heading-compound-assignment-operators-in-swift">Compound assignment operators in Swift</h3>
<p>The compound assignment operators combine the assignment operator with arithmetic operators:</p>
<ul>
<li><code>+=</code></li>
<li><code>-=</code></li>
<li><code>*=</code></li>
<li><code>/=</code></li>
<li><code>%=</code></li>
</ul>
<p>Example:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> age = <span class="hljs-number">8</span>
age += <span class="hljs-number">1</span>
</code></pre>
<h3 id="heading-comparison-operators-in-swift">Comparison operators in Swift</h3>
<p>Swift defines a few comparison operators:</p>
<ul>
<li><code>==</code></li>
<li><code>!=</code></li>
<li><code>&gt;</code></li>
<li><code>&lt;</code></li>
<li><code>&gt;=</code></li>
<li><code>&lt;=</code></li>
</ul>
<p>You can use those operators to get a boolean value (<code>true</code> or <code>false</code>) depending on the result:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> a = <span class="hljs-number">1</span>
<span class="hljs-keyword">let</span> b = <span class="hljs-number">2</span>

a == b <span class="hljs-comment">//false</span>
a != b <span class="hljs-comment">//true</span>
a &gt; b <span class="hljs-comment">// false</span>
a &lt;= b <span class="hljs-comment">//true</span>
</code></pre>
<h3 id="heading-range-operators-in-swift">Range operators in Swift</h3>
<p>Range operators are used in loops. They allow us to define a range:</p>
<pre><code class="lang-swift"><span class="hljs-number">0</span>...<span class="hljs-number">3</span> <span class="hljs-comment">//4 times</span>
<span class="hljs-number">0</span>..&lt;<span class="hljs-number">3</span> <span class="hljs-comment">//3 times</span>

<span class="hljs-number">0</span>...<span class="hljs-built_in">count</span> <span class="hljs-comment">//"count" times</span>
<span class="hljs-number">0</span>..&lt;<span class="hljs-built_in">count</span> <span class="hljs-comment">//"count-1" times</span>
</code></pre>
<p>Here's a sample usage:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> <span class="hljs-built_in">count</span> = <span class="hljs-number">3</span>
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-number">0</span>...<span class="hljs-built_in">count</span> {
  <span class="hljs-comment">//loop body</span>
}
</code></pre>
<h3 id="heading-logical-operators-in-swift">Logical operators in Swift</h3>
<p>Swift gives us the following logical operators:</p>
<ul>
<li><code>!</code>, the unary operator NOT</li>
<li><code>&amp;&amp;</code>, the binary operator AND</li>
<li><code>||</code>, the binary operator OR</li>
</ul>
<p>Sample usage:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> condition1 = <span class="hljs-literal">true</span>
<span class="hljs-keyword">let</span> condition2 = <span class="hljs-literal">false</span>

!condition1 <span class="hljs-comment">//false</span>

condition1 &amp;&amp; condition2 <span class="hljs-comment">//false</span>
condition1 || condition2 <span class="hljs-comment">//true</span>
</code></pre>
<p>Those are mostly used in the <code>if</code> conditional expression evaluation:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">if</span> condition1 &amp;&amp; condition2 {
  <span class="hljs-comment">//if body</span>
}
</code></pre>
<h2 id="heading-conditionals-in-swift">Conditionals in Swift</h2>
<h3 id="heading-if-statements-in-swift"><code>if</code> statements in Swift</h3>
<p><code>if</code> statements are the most popular way to perform a conditional check. We use the <code>if</code> keyword followed by a boolean expression, followed by a block containing code that is run if the condition is true:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> condition = <span class="hljs-literal">true</span>
<span class="hljs-keyword">if</span> condition == <span class="hljs-literal">true</span> {
    <span class="hljs-comment">// code executed if the condition is true</span>
}
</code></pre>
<p>An <code>else</code> block is executed if the condition is false:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> condition = <span class="hljs-literal">true</span>
<span class="hljs-keyword">if</span> condition == <span class="hljs-literal">true</span> {
    <span class="hljs-comment">// code executed if the condition is true</span>
} <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// code executed if the condition is false</span>
}
</code></pre>
<p>You can optionally wrap the condition validation into parentheses if you prefer:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">if</span> (condition == <span class="hljs-literal">true</span>) {
    <span class="hljs-comment">// ...</span>
}
</code></pre>
<p>And you can also just write:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">if</span> condition {
    <span class="hljs-comment">// runs if `condition` is `true`</span>
}
</code></pre>
<p>or</p>
<pre><code class="lang-swift"><span class="hljs-keyword">if</span> !condition {
    <span class="hljs-comment">// runs if `condition` is `false`</span>
}
</code></pre>
<p>One thing that separates Swift from many other languages is that it prevents bugs caused by erroneously doing an assignment instead of a comparison. This means you can't do this:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">if</span> condition = <span class="hljs-literal">true</span> {
    <span class="hljs-comment">// The program does not compile</span>
}
</code></pre>
<p>The reason is that the assignment operator does not return anything, but the <code>if</code> conditional must be a boolean expression.</p>
<h3 id="heading-switch-statements-in-swift"><code>switch</code> statements in Swift</h3>
<p>Switch statements are a handy way to create a conditional with multiple options:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> name = <span class="hljs-string">"Roger"</span>

<span class="hljs-keyword">switch</span> name {
<span class="hljs-keyword">case</span> <span class="hljs-string">"Roger"</span>:
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Hello, mr. Roger!"</span>)
<span class="hljs-keyword">default</span>: 
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Hello, \(name)"</span>)
}
</code></pre>
<p>When the code of a case ends, the switch exits automatically.</p>
<p>A switch in Swift needs to cover all cases. If the <em>tag</em>, <code>name</code> in this case, is a string that can have any value, we need to add a <code>default</code> case, mandatory.</p>
<p>Otherwise with an enumeration, you can simply list all the options:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-keyword">case</span> dog
    <span class="hljs-keyword">case</span> cat
}

<span class="hljs-keyword">var</span> animal: <span class="hljs-type">Animal</span> = .dog

<span class="hljs-keyword">switch</span> animal {
<span class="hljs-keyword">case</span> .dog:
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Hello, dog!"</span>)
<span class="hljs-keyword">case</span> .cat:
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Hello, cat!"</span>)
}
</code></pre>
<p>A case can be a Range:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> age = <span class="hljs-number">20</span>

<span class="hljs-keyword">switch</span> age {
<span class="hljs-keyword">case</span> <span class="hljs-number">0</span>..&lt;<span class="hljs-number">18</span>:
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"You can't drive!!"</span>)
<span class="hljs-keyword">default</span>: 
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"You can drive"</span>)
}
</code></pre>
<h3 id="heading-ternary-conditional-operator-in-swift">Ternary conditional operator in Swift</h3>
<p>The ternary conditional operator is a shorter version of an <code>if</code> expression. It allows us to execute an expression if a condition is true, and another expression if the condition is false.</p>
<p>Here is the syntax:</p>
<pre><code><span class="hljs-string">`condition`</span> ? <span class="hljs-string">`value if true`</span> : <span class="hljs-string">`value if false`</span>
</code></pre><p>Example:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> num1 = <span class="hljs-number">1</span>
<span class="hljs-keyword">let</span> num2 = <span class="hljs-number">2</span>

<span class="hljs-keyword">let</span> smallerNumber = num1 &lt; num2 ? num1 : num2 

<span class="hljs-comment">// smallerNumber == 1</span>
</code></pre>
<p>The syntax is shorter than an <code>if</code> statement, and sometimes it might make more sense to use it.</p>
<h2 id="heading-loops-in-swift">Loops in Swift</h2>
<h3 id="heading-for-in-loops-in-swift"><code>for-in</code> loops in Swift</h3>
<p>You can use <code>for-in</code> loops to iterate a specific amount of times, using a range operator:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">for</span> index <span class="hljs-keyword">in</span> <span class="hljs-number">0</span>...<span class="hljs-number">3</span> {
  <span class="hljs-comment">//iterate 4 times, `index` is: 0, 1, 2, 3</span>
}
</code></pre>
<p>You can iterate over the elements of an array or set:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> list = [<span class="hljs-string">"a"</span>, <span class="hljs-string">"b"</span>, <span class="hljs-string">"c"</span>]
<span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> list {
  <span class="hljs-comment">// `item` contains the element value</span>
}
</code></pre>
<p>And on the elements of a dictionary:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> list = [<span class="hljs-string">"a"</span>: <span class="hljs-number">1</span>, <span class="hljs-string">"b"</span>: <span class="hljs-number">2</span>, <span class="hljs-string">"c"</span>: <span class="hljs-number">2</span>]
<span class="hljs-keyword">for</span> (key, value) <span class="hljs-keyword">in</span> list {
  <span class="hljs-comment">// `key` contains the item key</span>
  <span class="hljs-comment">// `value` contains the item value</span>
}
</code></pre>
<h3 id="heading-while-loops-in-swift"><code>while</code> loops in Swift</h3>
<p>A <code>while</code> loop can be used to iterate on anything, and will run while the condition is <code>true</code>:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">while</span> [condition] {
    <span class="hljs-comment">//statements...</span>
}
</code></pre>
<p>The condition is checked at the start, before the loop block is executed.</p>
<p>Example:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> item = <span class="hljs-number">0</span>
<span class="hljs-keyword">while</span> item &lt;= <span class="hljs-number">3</span> { <span class="hljs-comment">//repeats 3 times</span>
    <span class="hljs-built_in">print</span>(item)
    item += <span class="hljs-number">1</span>
}
</code></pre>
<h3 id="heading-repeat-while-loops-in-swift"><code>repeat-while</code> loops in Swift</h3>
<p>A <code>repeat-while</code> loop in Swift is similar to the <code>while</code> loop. But in this case the condition is checked at the end, after the loop block, so the loop block is executed at least once. Then the condition is checked, and if it is evaluated as <code>true</code>, the loop block is repeated:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">repeat</span> {
    <span class="hljs-comment">//statements...</span>
} <span class="hljs-keyword">while</span> [condition]
</code></pre>
<p>Example:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> item = <span class="hljs-number">0</span>
<span class="hljs-keyword">repeat</span> { <span class="hljs-comment">//repeats 3 times</span>
    <span class="hljs-built_in">print</span>(item)
    item += <span class="hljs-number">1</span>
} <span class="hljs-keyword">while</span> item &lt; <span class="hljs-number">3</span>
</code></pre>
<h3 id="heading-continue-and-break-statements-in-swift"><code>continue</code> and <code>break</code> statements in Swift</h3>
<p>Swift provides you 2 statements that you can use to control the flow inside a loop: <code>continue</code> and <code>break</code>.</p>
<p>You use <code>continue</code> to stop the current iteration, and run the next iteration of the loop.</p>
<p><code>break</code> ends the loop, not executing any other iteration.</p>
<p>Example:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> list = [<span class="hljs-string">"a"</span>, <span class="hljs-string">"b"</span>, <span class="hljs-string">"c"</span>]
<span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> list {
  <span class="hljs-keyword">if</span> (item == <span class="hljs-string">"b"</span>) {
    <span class="hljs-keyword">break</span>
  }
  <span class="hljs-comment">//do something</span>
}
</code></pre>
<h2 id="heading-how-to-write-comments-in-swift">How to Write Comments in Swift</h2>
<p>A comment in Swift can take 2 forms: a single-line comment, and a multi-line comment.</p>
<p>A single-line comment looks like this:</p>
<pre><code class="lang-swift"><span class="hljs-comment">//this is a comment</span>
</code></pre>
<p>and and you can put it at the end of a line of code:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> a = <span class="hljs-number">1</span> <span class="hljs-comment">//this is a comment</span>
</code></pre>
<p>A multi-line comment is written using this syntax:</p>
<pre><code class="lang-swift"><span class="hljs-comment">/* this
 is
    a multi-line
 comment
*/</span>
</code></pre>
<p>Swift allows you to nest multi-line comments:</p>
<pre><code class="lang-swift"><span class="hljs-comment">/* this
 is
    a <span class="hljs-comment">/* nested */</span> multi-line
 comment
*/</span>
</code></pre>
<p>This is handy especially when commenting out large portions of code that already contain multi-line comments.</p>
<h2 id="heading-semicolons-in-swift">Semicolons in Swift</h2>
<p>In Swift, semicolons are generally optional.</p>
<p>You can write statements on separate lines, and you don't need to add a semicolon:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> list = [<span class="hljs-string">"a"</span>, <span class="hljs-string">"b"</span>, <span class="hljs-string">"c"</span>]
<span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>
</code></pre>
<p>You <em>can</em> add a semicolon, but it adds nothing meaningful in this case:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> list = [<span class="hljs-string">"a"</span>, <span class="hljs-string">"b"</span>, <span class="hljs-string">"c"</span>];
<span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>;
</code></pre>
<p>But if you want to write more than one statement on the same line, then you need to add a semicolon:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span>; <span class="hljs-keyword">let</span> b = <span class="hljs-number">3</span>
</code></pre>
<h2 id="heading-numbers-in-swift">Numbers in Swift</h2>
<p>In Swift, numbers have 2 main types: <code>Int</code> and <code>Double</code>.</p>
<p>An <code>Int</code> is a number without decimal point. A <code>Double</code> is a number with decimal point.</p>
<p>Both use 64 bits, on modern computers that work with 64 bits, and 32 bit on 32-bit platforms.</p>
<p>The range of values they can store depends on the platform used, and can be retrieved using the <code>int</code> property of each type:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2020-11-02-at-07.41.09.png" alt="Image" width="600" height="400" loading="lazy">
<em>Range of int values</em></p>
<p>Then, in addition to <code>Int</code> and <code>Double</code>, we have lots of other numeric types. These were mostly used to interact with APIs built in the past and that needed to interact with C or Objective-C, and you must be aware that we have them:</p>
<ul>
<li><code>Int8</code> is an integer with 8 bits</li>
<li><code>Int16</code> is an integer with 16 bits</li>
<li><code>Int32</code> is an integer with 32 bits</li>
<li><code>Int64</code> is an integer with 64 bits</li>
<li><code>UInt8</code> is an unsigned integer with 8 bits</li>
<li><code>UInt16</code> is an unsigned integer with 16 bits</li>
<li><code>UInt32</code> is an unsigned integer with 32 bits</li>
<li><code>UInt64</code> is an unsigned integer with 64 bits</li>
<li><code>UInt</code> is like <code>Int</code>, but unsigned, and it ranges from 0 to <code>Int.max * 2</code>.</li>
<li><code>Float</code> is a decimal number with 32 bits.</li>
</ul>
<p>Then using Cocoa APIs you might use other numeric types like CLong, CGFloat, and more.</p>
<p>You will always use <code>Int</code> or <code>Double</code> in your code, and use those specific types only in particular cases.</p>
<p>Remember that you can always convert any of those types to <code>Int</code> and <code>Double</code> types, instantiating a number passing the value inside parentheses to <code>Double()</code> or <code>Int()</code>:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> age : <span class="hljs-type">UInt8</span> = <span class="hljs-number">3</span>
<span class="hljs-keyword">let</span> intAge = <span class="hljs-type">Int</span>(age)
</code></pre>
<p>You can also convert a number from <code>Double</code> to <code>Int</code>:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> age = <span class="hljs-type">Double</span>(<span class="hljs-number">3</span>)
<span class="hljs-keyword">let</span> <span class="hljs-built_in">count</span> = <span class="hljs-type">Int</span>(<span class="hljs-number">3.14</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2020-11-02-at-07.59.19.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to convert a number from <code>Double</code> to <code>Int</code></em></p>
<h2 id="heading-strings-in-swift">Strings in Swift</h2>
<p>Strings are one of the most popular tools in programming.</p>
<p>In Swift, you can define a string using the string literal syntax:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> name = <span class="hljs-string">"Roger"</span>
</code></pre>
<p>We use double quotes. Single quotes are not valid string delimiters.</p>
<p>A string can span over multiple lines using 3 double quotes:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> description = <span class="hljs-string">"""
    a long
      long 
          long description
    """</span>
</code></pre>
<p>You can use string interpolation to embed an expression in a string:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> age = <span class="hljs-number">8</span>

<span class="hljs-keyword">let</span> name = <span class="hljs-string">"""
    Roger, age \(age)
    Next year he will be \(age + 1)
    """</span>
</code></pre>
<p>You can concatenate two strings with the <code>+</code> operator:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> name = <span class="hljs-string">"Roger"</span>
name = name + <span class="hljs-string">" The Dog"</span>
</code></pre>
<p>And you can append text to a string with the <code>+=</code> operator:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> name = <span class="hljs-string">"Roger"</span>
name += <span class="hljs-string">" The Dog"</span>
</code></pre>
<p>Or using the <code>append(_:)</code> method:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> name = <span class="hljs-string">"Roger"</span>
name.append(<span class="hljs-string">" The Dog"</span>)
</code></pre>
<p>You can count the characters in a string using the <code>count</code> string property:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> name = <span class="hljs-string">"Roger"</span>
name.<span class="hljs-built_in">count</span> <span class="hljs-comment">//5</span>
</code></pre>
<p>Any string comes with a set of useful methods, for example:</p>
<ul>
<li><code>removeFirst()</code> to remove the first character</li>
<li><code>removeLast()</code> to remove the last character</li>
<li><code>lowercased()</code> to get a new string, lowercased</li>
<li><code>uppercased()</code> to get a new string, uppercased</li>
<li><code>starts(with:)</code> which returns true if the string starts with a specific substring</li>
<li><code>contains()</code> which returns true if the string contains a specific character</li>
</ul>
<p>and many, many more.</p>
<p>When you need to reference an item in the string, since strings in Swift are unicode, we can't simply reference the letter <code>o</code> in <code>let name = "Roger"</code> using <code>name[1]</code>. You need to work with indexes.</p>
<p>Any string provides the starting index with the <code>startIndex</code> property:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> name = <span class="hljs-string">"Roger"</span>
name.startIndex <span class="hljs-comment">//0</span>
</code></pre>
<p>To calculate a specific index in the string, you calculate it using the <code>index(i:offsetBy:)</code> method:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> name = <span class="hljs-string">"Roger"</span>
<span class="hljs-keyword">let</span> i = name.index(name.startIndex, offsetBy: <span class="hljs-number">2</span>)
name[i] <span class="hljs-comment">//"g"</span>
</code></pre>
<p>You can also use the index to get a substring:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> name = <span class="hljs-string">"Roger"</span>
<span class="hljs-keyword">let</span> i = name.index(name.startIndex, offsetBy: <span class="hljs-number">2</span>)
name.suffix(from: i) <span class="hljs-comment">//"ger"</span>

<span class="hljs-comment">//Or using the subscript:</span>

name[i...] <span class="hljs-comment">//"ger"</span>
</code></pre>
<p>When you get a substring from a string, the type of the result is <code>Substring</code>, not <code>String</code>.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> name = <span class="hljs-string">"Roger"</span>
<span class="hljs-keyword">let</span> i = name.index(name.startIndex, offsetBy: <span class="hljs-number">2</span>)
<span class="hljs-built_in">print</span>(type(of: name.suffix(from: i))) 
<span class="hljs-comment">//Substring</span>
</code></pre>
<p>Substrings are more memory efficient, because you do not get a new string, but the same memory structure is used behind the scenes. But you need to be careful when you deal with strings a lot, as there are optimizations you can implement.</p>
<p>Strings are collections, and they can be iterated over in loops.</p>
<h2 id="heading-booleans-in-swift">Booleans in Swift</h2>
<p>Swift provides the <code>Bool</code> type, which can have two values: <code>true</code> and <code>false</code>.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> done = <span class="hljs-literal">false</span>
done = <span class="hljs-literal">true</span>
</code></pre>
<p>Booleans are especially useful with conditional control structures like <code>if</code> statements or the ternary conditional operator:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> done = <span class="hljs-literal">true</span>

<span class="hljs-keyword">if</span> done == <span class="hljs-literal">true</span> {
    <span class="hljs-comment">//code</span>
}
</code></pre>
<h2 id="heading-arrays-in-swift">Arrays in Swift</h2>
<p>We use arrays to create a collection of items.</p>
<p>In this example we create an array holding 3 integers:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
</code></pre>
<p>We can access the first item using the syntax <code>list[0]</code>, the second using <code>list[1]</code>, and so on.</p>
<p>Elements in an array in Swift must have the same type.</p>
<p>The type can be inferred if you initialize the array at declaration time, like in the case above.</p>
<p>Otherwise the type of values an array can include must be declared, in this way:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list: [<span class="hljs-type">Int</span>] = []
</code></pre>
<p>Another shorthand syntax is:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list = [<span class="hljs-type">Int</span>]()
</code></pre>
<p>You can also explicitly declare the type at initialization, like this:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list: [<span class="hljs-type">Int</span>] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
</code></pre>
<p>A quick way to initialize an array is to use the range operator:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list = <span class="hljs-type">Array</span>(<span class="hljs-number">1</span>...<span class="hljs-number">4</span>) <span class="hljs-comment">//[1, 2, 3, 4]</span>
</code></pre>
<p>To get the number of items in the array, use the <code>count</code> property:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
list.<span class="hljs-built_in">count</span> <span class="hljs-comment">//3</span>
</code></pre>
<p>If an array is empty, its <code>isEmpty</code> property is <code>true</code>.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
list.isEmpty <span class="hljs-comment">//false</span>
</code></pre>
<p>You can append an item at the end of the array using the <code>append()</code> method:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list: [<span class="hljs-type">Int</span>] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
list.append(<span class="hljs-number">4</span>)
</code></pre>
<p>or you can insert an item at any position of the array using <code>insert(newElement: &lt;Type&gt; at: Int)</code>:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list: [<span class="hljs-type">Int</span>] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
list.insert(<span class="hljs-number">17</span>, at: <span class="hljs-number">2</span>)
<span class="hljs-comment">//list is [1, 2, 17, 3]</span>
</code></pre>
<p>An array must be declared as <code>var</code> to be modified. If it's declared with <code>let</code>, you cannot modify it by adding or removing elements.</p>
<p>To remove one item from the array, use <code>remove(at:)</code> passing the index of the element to remove:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list: [<span class="hljs-type">Int</span>] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
list.remove(<span class="hljs-number">1</span>)
<span class="hljs-comment">//list is [1, 3]</span>
</code></pre>
<p><code>removeLast()</code> and <code>removeFirst()</code> are two handy ways to remove the last and first element.</p>
<p>To remove all items from the array, you can use <code>removeAll()</code> or you can assign an empty array:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list: [<span class="hljs-type">Int</span>] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
list.removeAll()
<span class="hljs-comment">//or</span>
list = []
</code></pre>
<p>The <code>sort()</code> method sorts the array:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> list = [<span class="hljs-number">3</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>]
list.<span class="hljs-built_in">sort</span>()
<span class="hljs-comment">//list is [1, 2, 3]</span>
</code></pre>
<p>There are a lot more methods, but those are the basic ones.</p>
<p>Arrays are equal when they contain the same elements, of the same type:</p>
<pre><code class="lang-swift">[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>] == [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>] <span class="hljs-comment">//true</span>
</code></pre>
<p>Arrays are passed by value, which means if you pass an array to a function, or return it from a function, the array is copied.</p>
<p>Arrays are collections, and they can be iterated over in loops.</p>
<h2 id="heading-sets-in-swift">Sets in Swift</h2>
<p>You use sets to create collections of non-repeated items.</p>
<p>While an array can contain many times the same item, you only have unique items in a set.</p>
<p>You can declare a set of <code>Int</code> values in this way:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> <span class="hljs-keyword">set</span>: <span class="hljs-type">Set</span>&lt;<span class="hljs-type">Int</span>&gt; = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
</code></pre>
<p>or you can initialize it from an array:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> <span class="hljs-keyword">set</span> = <span class="hljs-type">Set</span>([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>])
</code></pre>
<p>You can add items to the set using <code>insert()</code>:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> <span class="hljs-keyword">set</span> = <span class="hljs-type">Set</span>([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>])
<span class="hljs-keyword">set</span>.insert(<span class="hljs-number">17</span>)
</code></pre>
<p>Unlike arrays, there is no order or position in a set. Items are retrieved and inserted randomly.</p>
<p>The way to print the content of a set so it's ordered is to transform it into an array using the <code>sorted()</code> method:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> <span class="hljs-keyword">set</span> = <span class="hljs-type">Set</span>([<span class="hljs-number">2</span>, <span class="hljs-number">1</span>, <span class="hljs-number">3</span>])
<span class="hljs-keyword">let</span> orderedList = <span class="hljs-keyword">set</span>.sorted()
</code></pre>
<p>To check if a set contains an element, use the <code>contains()</code> method:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> <span class="hljs-keyword">set</span> = <span class="hljs-type">Set</span>([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>])
<span class="hljs-keyword">set</span>.<span class="hljs-built_in">contains</span>(<span class="hljs-number">2</span>) <span class="hljs-comment">//true</span>
</code></pre>
<p>To get the number of items in the set, use the <code>count</code> property:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> <span class="hljs-keyword">set</span> = <span class="hljs-type">Set</span>([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>])
<span class="hljs-keyword">set</span>.<span class="hljs-built_in">count</span> <span class="hljs-comment">//3</span>
</code></pre>
<p>If a set is empty, its <code>isEmpty</code> property is <code>true</code>.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> <span class="hljs-keyword">set</span> = <span class="hljs-type">Set</span>([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>])
<span class="hljs-keyword">set</span>.isEmpty <span class="hljs-comment">//false</span>
</code></pre>
<p>To remove one item from the array, use <code>remove()</code> passing the value of the element:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> <span class="hljs-keyword">set</span> = <span class="hljs-type">Set</span>([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>])
<span class="hljs-keyword">set</span>.remove(<span class="hljs-number">1</span>)
<span class="hljs-comment">//set is [2, 3]</span>
</code></pre>
<p>To remove all items from the set, you can use <code>removeAll()</code>:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">set</span>.removeAll()
</code></pre>
<p>Sets, like arrays, are passed by value. This means that if you pass it to a function, or return it from a function, the set is copied.</p>
<p>Sets are great to perform set math operations like intersection, union, subtracting, and more.</p>
<p>These methods help with this:</p>
<ul>
<li><code>intersection(_:)</code></li>
<li><code>symmetricDifference(_:)</code></li>
<li><code>union(_:)</code></li>
<li><code>subtracting(_:)</code></li>
<li><code>isSubset(of:)</code></li>
<li><code>isSuperset(of:)</code></li>
<li><code>isStrictSubset(of:)</code></li>
<li><code>isStrictSuperset(of:)</code></li>
<li><code>isDisjoint(with:)</code></li>
</ul>
<p>Sets are collections, and they can be iterated over in loops.</p>
<h2 id="heading-dictionaries-in-swift">Dictionaries in Swift</h2>
<p>We use dictionaries to create a collection of key-value pairs.</p>
<p>Here is how to create a dictionary with 1 key-value pair, where the key is a String and the value is an Int:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> dict = [<span class="hljs-string">"Roger"</span>: <span class="hljs-number">8</span>, <span class="hljs-string">"Syd"</span>: <span class="hljs-number">7</span>]
</code></pre>
<p>In this case the type is inferred. You can also explicitly set the type at declaration time:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> dict: [<span class="hljs-type">String</span>: <span class="hljs-type">Int</span>] = [<span class="hljs-string">"Roger"</span>: <span class="hljs-number">8</span>, <span class="hljs-string">"Syd"</span>: <span class="hljs-number">7</span>]
</code></pre>
<p>In this example we create an empty dictionary of Int keys and String values:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> dict = [<span class="hljs-type">String</span>: <span class="hljs-type">Int</span>]()

<span class="hljs-comment">//or</span>

<span class="hljs-keyword">var</span> dict: [<span class="hljs-type">String</span>: <span class="hljs-type">Int</span>] = [:]
</code></pre>
<p>You can access the value assigned to a key using this syntax:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> dict = [<span class="hljs-string">"Roger"</span>: <span class="hljs-number">8</span>, <span class="hljs-string">"Syd"</span>: <span class="hljs-number">7</span>]

dict[<span class="hljs-string">"Roger"</span>] <span class="hljs-comment">//8</span>
dict[<span class="hljs-string">"Syd"</span>] <span class="hljs-comment">//7</span>
</code></pre>
<p>You can change the value assigned to a key in this way:</p>
<pre><code class="lang-swift">dict[<span class="hljs-string">"Roger"</span>] = <span class="hljs-number">9</span>
</code></pre>
<p>A dictionary must be declared as <code>var</code> to be modified. If it's declared with <code>let</code>, you cannot modify it by adding or removing elements.</p>
<p>Use the same syntax to add a new key/value pair:</p>
<pre><code class="lang-swift">dict[<span class="hljs-string">"Tina"</span>] = <span class="hljs-number">4</span>
</code></pre>
<p>To remove a key/value pair, assign the value to <code>nil</code>:</p>
<pre><code class="lang-swift">dict[<span class="hljs-string">"Tina"</span>] = <span class="hljs-literal">nil</span>
</code></pre>
<p>Or call the <code>removeValue(forKey:)</code> method:</p>
<pre><code class="lang-swift">dict.removeValue(forKey: <span class="hljs-string">"Tina"</span>)
</code></pre>
<p>To get the number of items in the dictionary, use the <code>count</code> property:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> dict = [<span class="hljs-string">"Roger"</span>: <span class="hljs-number">8</span>, <span class="hljs-string">"Syd"</span>: <span class="hljs-number">7</span>]
dict.<span class="hljs-built_in">count</span> <span class="hljs-comment">//2</span>
</code></pre>
<p>If a dictionary is empty, its <code>isEmpty</code> property is <code>true</code>.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> dict = [<span class="hljs-type">String</span>: <span class="hljs-type">Int</span>]()
dict.isEmpty <span class="hljs-comment">//true</span>
</code></pre>
<p>There are a lot of methods related to dictionaries, but those are the basic ones.</p>
<p>Dictionaries are passed by value, which means if you pass it to a function, or return it from a function, the dictionary is copied.</p>
<p>Dictionaries are collections, and they can be iterated over in loops.</p>
<h2 id="heading-tuples-in-swift">Tuples in Swift</h2>
<p>You use tuples to group multiple values into a single collection. For example you can declare a variable <code>dog</code> containing a String and an Int value:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> dog : (<span class="hljs-type">String</span>, <span class="hljs-type">Int</span>)
</code></pre>
<p>And you can initialize them with a name and an age</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> dog : (<span class="hljs-type">String</span>, <span class="hljs-type">Int</span>) = (<span class="hljs-string">"Roger"</span>, <span class="hljs-number">8</span>)
</code></pre>
<p>But as with any other variable, the type can be inferred during initialization:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> dog = (<span class="hljs-string">"Roger"</span>, <span class="hljs-number">8</span>)
</code></pre>
<p>You can use named elements:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> dog = (name: <span class="hljs-string">"Roger"</span>, age: <span class="hljs-number">8</span>)

dog.name <span class="hljs-comment">//"Roger"</span>
dog.age <span class="hljs-comment">//8</span>
</code></pre>
<p>Once a tuple is defined, you can decompose it to individual variables in this way:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> dog = (<span class="hljs-string">"Roger"</span>, <span class="hljs-number">8</span>)
<span class="hljs-keyword">let</span> (name, age) = dog
</code></pre>
<p>and if you need to just get one of the values, you can use the special underscore keyword to ignore the other ones:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> dog = (<span class="hljs-string">"Roger"</span>, <span class="hljs-number">8</span>)
<span class="hljs-keyword">let</span> (name, <span class="hljs-number">_</span>) = dog
</code></pre>
<p>Tuples are an awesome tool for various needs.</p>
<p>The most obvious one is that they're a short way to group similar data.</p>
<p>Another one of those needs is returning multiple items from a function. A function can only return a single item, so a tuple is a convenient structure for that.</p>
<p>Another handy functionality allowed by tuples is swapping elements:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> a = <span class="hljs-number">1</span>
<span class="hljs-keyword">var</span> b = <span class="hljs-number">2</span>

(a, b) = (b, a)

<span class="hljs-comment">//a == 2</span>
<span class="hljs-comment">//b == 1</span>
</code></pre>
<h2 id="heading-optionals-and-nil-in-swift">Optionals and <code>nil</code> in Swift</h2>
<p>Optionals are one key feature of Swift.</p>
<p>When you don't know if a value will be present or absent, you declare the type as an optional.</p>
<p>The optional wraps another value with its own type. Or maybe not.</p>
<p>We declare an optional by adding a question mark after its type, like this:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> value: <span class="hljs-type">Int?</span> = <span class="hljs-number">10</span>
</code></pre>
<p>Now <code>value</code> is not an Int value. It's an optional wrapping an Int value.</p>
<p>To find out if the optional wraps a value, you must <strong>unwrap</strong> it.</p>
<p>You do so using an exclamation mark:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> value: <span class="hljs-type">Int?</span> = <span class="hljs-number">10</span>
<span class="hljs-built_in">print</span>(value!) <span class="hljs-comment">//10</span>
</code></pre>
<p>Swift methods often return an optional. For example the <code>Int</code> type initializer accepts a string, and returns an Int optional:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2020-11-02-at-18.08.48.png" alt="Image" width="600" height="400" loading="lazy">
<em>Int type initializer takes in a string and returns an int optional</em></p>
<p>This is because it does not know if the string can be converted to a number.</p>
<p>If the optional does not contain a value, it evaluates as <code>nil</code>, and you cannot unwrap it:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2020-11-02-at-18.12.13.png" alt="Image" width="600" height="400" loading="lazy">
<em>Evaluating to <code>nil</code></em></p>
<p><code>nil</code> is a special value that cannot be assigned to a variable. Only to an optional:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2020-11-02-at-18.14.21.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2020-11-02-at-18.13.56-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>You can only assign <code>nil</code> to an optional (not an int)</em></p>
<p>You typically use <code>if</code> statements to unwrap values in your code, like this:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> value: <span class="hljs-type">Int?</span> = <span class="hljs-number">2</span>

<span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> age = value {
    <span class="hljs-built_in">print</span>(age)
}
</code></pre>
<h2 id="heading-enumerations-in-swift">Enumerations in Swift</h2>
<p>Enumerations are a way to group a set of different options under a common name.</p>
<p>Example:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-keyword">case</span> dog
    <span class="hljs-keyword">case</span> cat
    <span class="hljs-keyword">case</span> mouse
    <span class="hljs-keyword">case</span> horse
}
</code></pre>
<p>This <code>Animal</code> enum is now a <strong>type</strong>.</p>
<p>A type whose value can only be one of the cases listed.</p>
<p>If you define a variable of type <code>Animal</code>:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> animal: <span class="hljs-type">Animal</span>
</code></pre>
<p>you can later decide which value to assign it using this syntax:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> animal: <span class="hljs-type">Animal</span>
animal = .dog
</code></pre>
<p>We can use enumerations in control structures like switches:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-keyword">case</span> dog
    <span class="hljs-keyword">case</span> cat
    <span class="hljs-keyword">case</span> mouse
    <span class="hljs-keyword">case</span> horse
}

<span class="hljs-keyword">let</span> animal = <span class="hljs-type">Animal</span>.dog

<span class="hljs-keyword">switch</span> animal {
<span class="hljs-keyword">case</span> .dog: <span class="hljs-built_in">print</span>(<span class="hljs-string">"dog"</span>)
<span class="hljs-keyword">case</span> .cat: <span class="hljs-built_in">print</span>(<span class="hljs-string">"cat"</span>)
<span class="hljs-keyword">default</span>: <span class="hljs-built_in">print</span>(<span class="hljs-string">"another animal"</span>)
}
</code></pre>
<p>Enumeration values can be strings, characters, or numbers.</p>
<p>You can also define an enum on a single line:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-keyword">case</span> dog, cat, mouse, horse
}
</code></pre>
<p>And you can also add type declaration to the enumeration, and each case has a value of that type assigned:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Animal</span>: <span class="hljs-title">Int</span> </span>{
    <span class="hljs-keyword">case</span> dog = <span class="hljs-number">1</span>
    <span class="hljs-keyword">case</span> cat = <span class="hljs-number">2</span>
    <span class="hljs-keyword">case</span> mouse = <span class="hljs-number">3</span>
    <span class="hljs-keyword">case</span> horse = <span class="hljs-number">4</span>
}
</code></pre>
<p>Once you have a variable, you can get this value using its <code>rawValue</code> property:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Animal</span>: <span class="hljs-title">Int</span> </span>{
    <span class="hljs-keyword">case</span> dog = <span class="hljs-number">1</span>
    <span class="hljs-keyword">case</span> cat = <span class="hljs-number">2</span>
    <span class="hljs-keyword">case</span> mouse = <span class="hljs-number">3</span>
    <span class="hljs-keyword">case</span> horse = <span class="hljs-number">4</span>
}

<span class="hljs-keyword">var</span> animal: <span class="hljs-type">Animal</span>
animal = .dog

animal.rawValue <span class="hljs-comment">//1</span>
</code></pre>
<p>Enumerations are a value type. This means they are copied when passed to a function, or when returned from a function. And when we assign a variable pointing to an enumeration to another variable.</p>
<h2 id="heading-structures-in-swift">Structures in Swift</h2>
<p>Structures are an essential Swift concept.</p>
<p>Structures are everywhere in Swift. Even the built-in types are structures.</p>
<p>We can create instances of structures, which we call <strong>objects</strong>.</p>
<p>In most languages, objects can only be created from classes. Swift has classes, too, but you can create objects also from structures. The official documentation actually advises that you should prefer structures because they are easier to use.</p>
<p>Structures are a light versions of classes.</p>
<p>A struct can:</p>
<ul>
<li>have properties</li>
<li>have methods (functions)</li>
<li>define subscripts</li>
<li>define initializers</li>
<li>conform to protocols</li>
<li>be extended</li>
</ul>
<p>One important thing classes allow is inheritance, so if you need that, you have classes.</p>
<p>A struct is defined using this syntax:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Dog</span> </span>{

}
</code></pre>
<p>Inside a structure you can define <strong>stored properties</strong>:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Dog</span> </span>{
    <span class="hljs-keyword">var</span> age = <span class="hljs-number">8</span>
    <span class="hljs-keyword">var</span> name = <span class="hljs-string">"Roger"</span>
}
</code></pre>
<p>This structure definition defines a <strong>type</strong>. To create a new instance with this type, we use this syntax:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> roger = <span class="hljs-type">Dog</span>()
</code></pre>
<p>Once you have an instance, you can access its properties using the dot syntax:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> roger = <span class="hljs-type">Dog</span>()
roger.age
roger.name
</code></pre>
<p>The same dot syntax is used to update a property value:</p>
<pre><code class="lang-swift">roger.age = <span class="hljs-number">9</span>
</code></pre>
<p>You can also create a struct instance by passing the values of the properties:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> syd = <span class="hljs-type">Dog</span>(age: <span class="hljs-number">7</span>, name: <span class="hljs-string">"Syd"</span>)
syd.age
syd.name
</code></pre>
<p>To do so, properties must be defined variables with <code>var</code>, not as constants (with <code>let</code>). It's also important to respect the order those properties are defined.</p>
<p>Structures can have <strong>instance methods</strong>: functions that belong to an instance of a structure.</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Dog</span> </span>{
    <span class="hljs-keyword">var</span> age = <span class="hljs-number">8</span>
    <span class="hljs-keyword">var</span> name = <span class="hljs-string">"Roger"</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bark</span><span class="hljs-params">()</span></span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"\(name): wof!"</span>)
    }
}
</code></pre>
<p>And we also have <strong>type methods</strong>:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Dog</span> </span>{
    <span class="hljs-keyword">var</span> age = <span class="hljs-number">8</span>
    <span class="hljs-keyword">var</span> name = <span class="hljs-string">"Roger"</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bark</span><span class="hljs-params">()</span></span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"\(name): wof!"</span>)
    }
    <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">hello</span><span class="hljs-params">()</span></span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"Hello I am the Dog struct"</span>)
    }
}
</code></pre>
<p>This is invoked as <code>Dog.hello()</code>.</p>
<p>Structures are a value type. This means they are copied when passed to a function, or when returned from a function. And when we assign a variable pointing to a structure to another variable.</p>
<p>This also means that if we want to update the properties of a structure we must define it using <code>var</code> and not <code>let</code>.</p>
<p>All types in Swift are defined as structures: Int, Double, String, arrays and dictionaries, and more are structures.</p>
<h2 id="heading-classes-in-swift">Classes in Swift</h2>
<p>Classes are a bit similar to structures, but they have some key differences.</p>
<p>A class is defined using this syntax:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> </span>{

}
</code></pre>
<p>Inside a class you can define stored properties:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> </span>{
    <span class="hljs-keyword">var</span> age = <span class="hljs-number">0</span>
}
</code></pre>
<p>A class definition defines a <strong>type</strong>. To create a new instance with this type, we use this syntax:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> roger = <span class="hljs-type">Dog</span>()
</code></pre>
<p>Once you have an instance, you can access its properties using the dot syntax:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> roger = <span class="hljs-type">Dog</span>()
roger.age
</code></pre>
<p>You use the same dot syntax to update a property value:</p>
<pre><code class="lang-swift">roger.age = <span class="hljs-number">9</span>
</code></pre>
<p>One big difference is that classes are reference types. Structures (and enumerations) are value types.</p>
<p>This means that assigning a class instance to another variable does not copy the instance. Both variables point to the same instance:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> </span>{
    <span class="hljs-keyword">var</span> age = <span class="hljs-number">0</span>
}

<span class="hljs-keyword">let</span> roger = <span class="hljs-type">Dog</span>()
<span class="hljs-keyword">let</span> syd = roger

roger.age = <span class="hljs-number">9</span>
<span class="hljs-comment">//syd.age == 9</span>
</code></pre>
<p>This also means we can define a reference to a class using <code>let</code>, and we can change its properties, as you saw in the example above.</p>
<p>We can create instances of classes, and we call them <strong>objects</strong>.</p>
<p>As with structs, classes can have properties, methods, and more.</p>
<p>Contrary to structs, we <strong>must</strong> define an initializer in order to initialize the values when we create an instance:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> </span>{
    <span class="hljs-keyword">var</span> age : <span class="hljs-type">Int</span>

    <span class="hljs-keyword">init</span>(age: <span class="hljs-type">Int</span>) {
        <span class="hljs-keyword">self</span>.age = age
    }
}

<span class="hljs-keyword">let</span> roger = <span class="hljs-type">Dog</span>(age: <span class="hljs-number">9</span>)
</code></pre>
<p>You can only declare properties without initializing them if you have an initializer.</p>
<p>See the use of <code>self</code>. We need it because <code>age</code> is both an instance property and the <code>init(age:)</code> method parameter. <code>self.age</code> references the <code>age</code> instance property.</p>
<p>Classes can have <strong>instance methods</strong>: functions that belong to an instance of a class.</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> </span>{
    <span class="hljs-keyword">var</span> age = <span class="hljs-number">8</span>
    <span class="hljs-keyword">var</span> name = <span class="hljs-string">"Roger"</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bark</span><span class="hljs-params">()</span></span> {
      <span class="hljs-built_in">print</span>(<span class="hljs-string">"\(name): wof!"</span>)
    }
}
</code></pre>
<p>And we also have <strong>type methods</strong>:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> </span>{
    <span class="hljs-keyword">var</span> age = <span class="hljs-number">8</span>
    <span class="hljs-keyword">var</span> name = <span class="hljs-string">"Roger"</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bark</span><span class="hljs-params">()</span></span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"\(name): wof!"</span>)
    }
    <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">hello</span><span class="hljs-params">()</span></span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"Hello I am the Dog struct"</span>)
    }
}
</code></pre>
<p>Invoked as <code>Dog.hello()</code>.</p>
<p>One important thing classes allow is inheritance.</p>
<p>A class can inherit all the properties and methods from another class.</p>
<p>Say we have a class <code>Animal</code>. Every animal has an age:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-keyword">var</span> age: <span class="hljs-type">Int</span>
}
</code></pre>
<p>Not every animal has a name. Dogs have a name. So we create a <code>Dog</code> class extending from <code>Animal</code>:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span>: <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-keyword">var</span> name: <span class="hljs-type">String</span>
}
</code></pre>
<p>Now we must add an initializer for both classes. In the Dog case, after we do the class-specific initialization, we can call the parent class initializer using <code>super.init()</code>:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-keyword">var</span> age: <span class="hljs-type">Int</span>

    <span class="hljs-keyword">init</span>(age: <span class="hljs-type">Int</span>) {
        <span class="hljs-keyword">self</span>.age = age
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span>: <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-keyword">var</span> name: <span class="hljs-type">String</span>

    <span class="hljs-keyword">init</span>(age: <span class="hljs-type">Int</span>, name: <span class="hljs-type">String</span>) {
        <span class="hljs-keyword">self</span>.name = name
        <span class="hljs-keyword">super</span>.<span class="hljs-keyword">init</span>(age: age)
    }
}

<span class="hljs-keyword">var</span> horse = <span class="hljs-type">Animal</span>(age: <span class="hljs-number">8</span>)
<span class="hljs-keyword">var</span> roger = <span class="hljs-type">Dog</span>(age: <span class="hljs-number">8</span>, name: <span class="hljs-string">"Roger"</span>)
</code></pre>
<p><code>Animal</code> is now a <strong>superclass</strong>, and <code>Dog</code> is a <strong>subclass</strong>.</p>
<p>There's more to say about classes, but this is a good introduction.</p>
<h2 id="heading-functions-in-swift">Functions in Swift</h2>
<p>Your program's code is organized into functions.</p>
<p>You can declare a function using the <code>func</code> keyword:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bark</span><span class="hljs-params">()</span></span> {
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"woof!"</span>)
}
</code></pre>
<p>Functions can be assigned to structures, classes and enumerations, and in this case we call them methods.</p>
<p>A function is invoked using its name:</p>
<pre><code class="lang-swift">bark()
</code></pre>
<p>A function can return a value:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bark</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">String</span> {
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"woof!"</span>)
      <span class="hljs-keyword">return</span> <span class="hljs-string">"barked successfully"</span>
}
</code></pre>
<p>And you can assign it to a variable:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> result = bark()
</code></pre>
<p>A function can accept parameters. Each parameter has a name and a type:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bark</span><span class="hljs-params">(times: Int)</span></span> {
    <span class="hljs-keyword">for</span> index <span class="hljs-keyword">in</span> <span class="hljs-number">0</span>..&lt;times {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"woof!"</span>)
    }
}
</code></pre>
<p>The name of a parameter is internal to the function.</p>
<p>We use the name of the parameter when we call the function to pass in its value:</p>
<pre><code class="lang-swift">bark(times: <span class="hljs-number">3</span>)
</code></pre>
<p>When we call the function we must pass all the parameters defined.</p>
<p>Here is a function that accepts multiple parameters:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bark</span><span class="hljs-params">(times: Int, repeatBark: Bool)</span></span> {
    <span class="hljs-keyword">for</span> index <span class="hljs-keyword">in</span> <span class="hljs-number">0</span>..&lt;times {
        <span class="hljs-keyword">if</span> repeatBark == <span class="hljs-literal">true</span> {
            <span class="hljs-built_in">print</span>(<span class="hljs-string">"woof woof!"</span>)
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">print</span>(<span class="hljs-string">"woof!"</span>)
        }            
    }
}
</code></pre>
<p>In this case you call it in this way:</p>
<pre><code class="lang-swift">bark(times: <span class="hljs-number">3</span>, <span class="hljs-keyword">repeat</span>: <span class="hljs-literal">true</span>)
</code></pre>
<p>When we talk about this function, we don't call it <code>bark()</code>. We call it <code>bark(times:repeat:)</code>.</p>
<p>This is because we can have multiple functions with the same name, but different set of parameters.</p>
<p>You can avoid using labels by using the <code>_</code> keyword:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bark</span><span class="hljs-params">(<span class="hljs-number">_</span> times: Int, repeatBark: Bool)</span></span> {
    <span class="hljs-comment">//...the function body</span>
}
</code></pre>
<p>So you can invoke it in this way:</p>
<pre><code class="lang-swift">bark(<span class="hljs-number">3</span>, <span class="hljs-keyword">repeat</span>: <span class="hljs-literal">true</span>)
</code></pre>
<p>It's common in Swift and iOS APIs to have the first parameter with no label, and the other parameters labeled.</p>
<p>It makes for a nice and expressive API, when you design the names of the function and the parameters nicely.</p>
<p>You can only return one value from a function. If you need to return multiple values, it's common to return a tuple:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bark</span><span class="hljs-params">()</span></span> -&gt; (<span class="hljs-type">String</span>, <span class="hljs-type">Int</span>) {
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"woof!"</span>)
      <span class="hljs-keyword">return</span> (<span class="hljs-string">"barked successfully"</span>, <span class="hljs-number">1</span>)
}
</code></pre>
<p>And you can assign the result to a tuple:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> (result, num) = bark()

<span class="hljs-built_in">print</span>(result) <span class="hljs-comment">//"barked successfully"</span>
<span class="hljs-built_in">print</span>(num) <span class="hljs-comment">//1</span>
</code></pre>
<p>You can nest functions inside other functions. When this happens, the inner function is invisible to outside the outer function.</p>
<h2 id="heading-protocols-in-swift">Protocols in Swift</h2>
<p>A protocol is a way to have different objects, of different types, have a common set of functionalities.</p>
<p>You define a protocol like this:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">protocol</span> <span class="hljs-title">Mammal</span> </span>{

}
</code></pre>
<p>Structs and classes can <strong>adopt a protocol</strong> in this way:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Dog</span>: <span class="hljs-title">Mammal</span> </span>{

}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span>: <span class="hljs-title">Mammal</span> </span>{

}
</code></pre>
<p>A protocol can define properties and methods, without providing values and implementations, and a struct/class must implement them:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">protocol</span> <span class="hljs-title">Mammal</span> </span>{
    <span class="hljs-keyword">var</span> age: <span class="hljs-type">Int</span> { <span class="hljs-keyword">get</span> <span class="hljs-keyword">set</span> }
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">walk</span><span class="hljs-params">()</span></span>
}
</code></pre>
<p>The property can be defined as <code>get</code> or <code>get set</code>. If it's <code>get</code>, the property must be implemented as read only, with a getter.</p>
<p>Any type that adopts the protocol must <strong>conform</strong> to the protocol by implementing those methods or providing those properties:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Dog</span>: <span class="hljs-title">Mammal</span> </span>{
    <span class="hljs-keyword">var</span> age: <span class="hljs-type">Int</span> = <span class="hljs-number">0</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">walk</span><span class="hljs-params">()</span></span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"The dog is walking"</span>)
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span>: <span class="hljs-title">Mammal</span> </span>{
    <span class="hljs-keyword">var</span> age: <span class="hljs-type">Int</span> = <span class="hljs-number">0</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">walk</span><span class="hljs-params">()</span></span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"The cat is walking"</span>)
    }
}
</code></pre>
<p>Structs and classes can adopt multiple protocols:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Dog</span>: <span class="hljs-title">Mammal</span>, <span class="hljs-title">Animal</span> </span>{

}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span>: <span class="hljs-title">Mammal</span>, <span class="hljs-title">Animal</span> </span>{

}
</code></pre>
<p>Notice that for classes, this is the same syntax used to define a superclass. If there is a superclass, list it as the first item in the list, after the colon.</p>
<h2 id="heading-where-to-go-from-here">Where to Go From Here</h2>
<p>I hope this little handbook was useful in shining a light on how to get started with Swift. And I hope you are now interested to learn more about it!</p>
<p>I can now point you to a few places to learn more:</p>
<ul>
<li><a target="_blank" href="https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html">The official Swift Language Guide</a></li>
<li><a target="_blank" href="https://developer.apple.com/documentation/swift/swift-standard-library/">The Swift Standard Library</a></li>
<li><a target="_blank" href="https://developer.apple.com/videos/swift">WWDC Swift videos</a></li>
</ul>
<p><a target="_blank" href="https://thevalleyofcode.com/download/swift/">You can get a PDF and ePub version of this Swift Beginner's Handbook here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Implement a GameKit Leaderboard in SwiftUI ]]>
                </title>
                <description>
                    <![CDATA[ By Saamer Mansoor In this article we will talk about why and how to implement the GameCenter's Leaderboard within your app.  Why GameCenter is Making a Huge Revival You can make iPhone games without a scoreboard, but leaderboards can help make the ga... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-a-leaderboard-in-swiftui/</link>
                <guid isPermaLink="false">66d460c537bd2215d1e245bb</guid>
                
                    <category>
                        <![CDATA[ Apple ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SwiftUI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 19 Aug 2022 21:00:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/IMG_45B142A26F90-1-copy.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Saamer Mansoor</p>
<p>In this article we will talk about why and how to implement the <a target="_blank" href="https://developer.apple.com/design/human-interface-guidelines/technologies/game-center/leaderboards/">GameCenter's Leaderboard</a> within your app. </p>
<h2 id="heading-why-gamecenter-is-making-a-huge-revival">Why GameCenter is Making a Huge Revival</h2>
<p>You can make iPhone games without a scoreboard, but leaderboards can help make the game feel more competitive, like people are competing against one another around the World. </p>
<p>Instead of creating and managing your own backend, the GameCenter Leaderboard allows you to scale with traffic infinitely, skip an entire login page for authorization, get the Image, Name, and friends playing the same game – all without your users having to enter anything. </p>
<p>Especially with iOS 16, <a target="_blank" href="https://developer.apple.com/game-center/">Apple is investing more in improving it</a>, and driving more app usage, like through Push Notifications when your friend beats your score in the game.</p>
<p>In my journey of learning SwiftUI, I have been creating and publishing apps, because IMO that's the best way to learn. </p>
<p>There wasn't much updated documentation on how to do a lot of this, especially none with SwiftUI nor with the <a target="_blank" href="https://www.freecodecamp.org/news/make-rest-api-call-in-swiftui-in-2-minutes/">advent of async and await in Swift</a>. So I consolidated and simplified it for everyone to build amazing apps. So feel free to invite me to test your apps too!</p>
<h3 id="heading-pre-requisites">Pre-Requisites:</h3>
<ul>
<li>You'll need to have an <a target="_blank" href="https://developer.apple.com/programs/">Apple Developer</a> paid account</li>
<li>You have to create the <a target="_blank" href="https://support.magplus.com/hc/en-us/articles/203808708-iOS-Creating-App-IDs">App Id for your app</a> in the provisioning profiles section of the Apple Developer Portal</li>
<li>You have to <a target="_blank" href="https://support.staffbase.com/hc/en-us/articles/115003481992-Creating-an-App-Profile-in-App-Store-Connect">create the App in the iTunes Connect Connect</a> portal</li>
</ul>
<h2 id="heading-how-to-implement-your-ios-leaderboard-in-6-steps">How to Implement Your iOS Leaderboard in 6 Steps</h2>
<p>Most of the code logic for the leaderboard is in <a target="_blank" href="https://github.com/StairMasterClimber/mobile/blob/main/StairStepperMaster/StairStepperMaster/Views/LeadersTileView.swift">this file if you want to skip ahead</a>. Here's the steps as follows:</p>
<h3 id="heading-1-how-to-create-the-app-store-connect-leaderboard">1. How to Create the App Store Connect Leaderboard</h3>
<p><img src="https://user-images.githubusercontent.com/8262287/180824532-2e27ca8a-c1c0-4676-b439-f3ab09887271.png" alt="image" width="1348" height="754" loading="lazy">
<em>Screenshot from the Apple iTunes Connect Portal</em></p>
<p>Once you have created the app in the App Store Connect portal successfully, go to the Services tab for the app -&gt; and make sure you're in the GameCenter page.</p>
<p>Then add a new leaderboard using the "+" sign, which can either be "Classic" (scores never reset) or "Recurring" (scores reset based on your frequency settings).</p>
<p>Most games prefer a recurring leaderboard so that the leaderboard isn't cluttered with older impossible to reach high scores.</p>
<p>The LeaderboardID you input there is the one that you need to use in all the places in the code that ask for it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-122.png" alt="Image" width="600" height="400" loading="lazy">
<em>Details required to create a new Leaderboard</em></p>
<h3 id="heading-2-how-to-set-up-gamecenter-authentication">2. How to Set Up GameCenter Authentication</h3>
<p>First, you'll need to authenticate users to GameCenter in order for any of this functionality to work.</p>
<p>So we'll use this code to do that, which basically makes sure that you (GKLocalPlayer.local) are authenticated, or prints an error if there is one:</p>
<pre><code>func authenticateUser() {
    GKLocalPlayer.local.authenticateHandler = { vc, error <span class="hljs-keyword">in</span>
        guard error == nil <span class="hljs-keyword">else</span> {
            print(error?.localizedDescription ?? <span class="hljs-string">""</span>)
            <span class="hljs-keyword">return</span>
        }
    }
}
</code></pre><p>If the user is authenticated, you will see a little popup in the UI. If not, the user will be taken to a page to login to their GameCenter account.</p>
<p><img src="https://user-images.githubusercontent.com/8262287/180823235-cafefcfa-3d25-46e5-8524-d7f475b9a000.png" alt="image" width="464" height="94" loading="lazy">
<em>A sign that displays when a user is logged in</em></p>
<h3 id="heading-3-how-to-display-leaderboard-items-in-the-ui">3. How to Display Leaderboard Items in the UI</h3>
<p>In order to get the data away from the GameCenter ViewController leaderboards (GKLeaderboard), you need to use the <code>loadLeaderboards</code> . </p>
<p>You can switch up the <code>loadEntries</code> function from <code>.global</code> to <code>.friends</code> in order to only pull your friends. </p>
<p>You can also retrieve the image for each player by iterating over each player and performing a <code>loadPhoto</code>. </p>
<p>Using <code>NSRang(1...5)</code>, you can choose how many players to display. This pulls the users with the highest 5 scores from the leaderboard and returns none if there's no users, such as in the case when the cycle refreshes for a recurring Leaderboard.</p>
<p>This is what pulling data from a leaderboard could look like if you take advantage of async-await:</p>
<pre><code>func loadLeaderboard() <span class="hljs-keyword">async</span> {
    playersList.removeAll()
    Task{
        <span class="hljs-keyword">var</span> playersListTemp : [Player] = []
        <span class="hljs-keyword">let</span> leaderboards = <span class="hljs-keyword">try</span> <span class="hljs-keyword">await</span> GKLeaderboard.loadLeaderboards(IDs: [leaderboardIdentifier])
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> leaderboard = leaderboards.filter ({ $<span class="hljs-number">0.</span>baseLeaderboardID == self.leaderboardIdentifier }).first {
            <span class="hljs-keyword">let</span> allPlayers = <span class="hljs-keyword">try</span> <span class="hljs-keyword">await</span> leaderboard.loadEntries(<span class="hljs-keyword">for</span>: .global, <span class="hljs-attr">timeScope</span>: .allTime, <span class="hljs-attr">range</span>: NSRange(<span class="hljs-number">1.</span>.<span class="hljs-number">.5</span>))
            <span class="hljs-keyword">if</span> allPlayers<span class="hljs-number">.1</span>.count &gt; <span class="hljs-number">0</span> {
                <span class="hljs-keyword">try</span> <span class="hljs-keyword">await</span> allPlayers<span class="hljs-number">.1</span>.asyncForEach { leaderboardEntry <span class="hljs-keyword">in</span>
                    <span class="hljs-keyword">var</span> image = <span class="hljs-keyword">try</span> <span class="hljs-keyword">await</span> leaderboardEntry.player.loadPhoto(<span class="hljs-keyword">for</span>: .small)
                    playersListTemp.append(Player(name: leaderboardEntry.player.displayName, <span class="hljs-attr">score</span>:leaderboardEntry.formattedScore, <span class="hljs-attr">image</span>: image))
                                print(playersListTemp)
                    playersListTemp.sort{
                        $<span class="hljs-number">0.</span>score &lt; $<span class="hljs-number">1.</span>score
                    }
                }
            }
        }
        playersList = playersListTemp            
    }
}
</code></pre><p><img src="https://user-images.githubusercontent.com/8262287/180823292-2dee4f9a-4894-4442-9241-2ad1c84b1cf7.png" alt="image" width="622" height="240" loading="lazy">
<em>You can get leaderboard data into your app</em></p>
<h3 id="heading-4-how-to-call-functionality-in-swiftui-as-the-viewpage-appears">4. How to Call Functionality in SwiftUI as the View/Page Appears</h3>
<p>You can take advantage of the <code>onAppear</code> <a target="_blank" href="https://www.hackingwithswift.com/quick-start/swiftui/how-to-respond-to-view-lifecycle-events-onappear-and-ondisappear">lifecycle function of the view</a> to actually make the calls to authenticate and load, but you can also do it on the tap of a button if you prefer that:</p>
<pre><code>.onAppear(){
    <span class="hljs-keyword">if</span> !GKLocalPlayer.local.isAuthenticated {
        authenticateUser()
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> playersList.count == <span class="hljs-number">0</span> {
        Task{
            <span class="hljs-keyword">await</span> loadLeaderboard()
        }
    }
}
</code></pre><h3 id="heading-5-how-to-load-the-submitted-scores">5. How to Load the Submitted Scores</h3>
<p>In order to load the scores, you need to submit them as well. The <code>submitScore</code> function can help you with that.</p>
<ul>
<li>The <code>flightsClimbed</code> variable should contain the score that you would like to submit.</li>
<li>GameKit makes sure to only display your best score for the life of the leaderboard.</li>
<li>The <code>leaderboardId</code> contains the value that you manually enter in your App Store Connect account:</li>
</ul>
<pre><code>func leaderboard() <span class="hljs-keyword">async</span>{
    Task{
        <span class="hljs-keyword">try</span> <span class="hljs-keyword">await</span> GKLeaderboard.submitScore(
            flightsClimbed,
            <span class="hljs-attr">context</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">player</span>: GKLocalPlayer.local,
            <span class="hljs-attr">leaderboardIDs</span>: [<span class="hljs-string">"com.tfp.stairsteppermaster.flights"</span>]
        )
    }
    calculateAchievements()
}
</code></pre><h3 id="heading-6-how-to-display-the-gamecenter-viewcontroller-portal">6. How to display the GameCenter ViewController Portal</h3>
<p>When you're logged into GameCenter, a little annoying icon appears in the top right of your screen. When you tap on it, you are taken to the GameCenter ViewController. Luckily you can hide it if it's not part of your design, using <code>GKAccessPoint.shared.isActive = false</code>. </p>
<p>Since the GameCenter UI is a UIKit <code>ViewController</code> and not a simple SwiftUI <code>View</code>, you need to create this <a target="_blank" href="https://www.hackingwithswift.com/books/ios-swiftui/wrapping-a-uiviewcontroller-in-a-swiftui-view">UIViewControllerRepresentable</a> first (as you can <a target="_blank" href="https://github.com/StairMasterClimber/mobile/blob/main/StairStepperMaster/StairStepperMaster/Views/GameCenterView.swift">see here</a>), to launch GameCenter using a different button, </p>
<p>Once you add that file to your project, you can display the GameCenter portal simply using this: <code>GameCenterView(format: gameCenterViewControllerState)</code> where gameCenterViewControllerState can be help you go to a detail page in GameCenter.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/Frame-3-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>GameCenter's Leaderboard View</em></p>
<h2 id="heading-things-to-keep-in-mind-while-using-gamecenters-leaderboards">Things to Keep in Mind While using GameCenter's Leaderboards:</h2>
<ul>
<li>Simulator Debugging – For some reason the authenticate to GameCenter is extremely slow on a simulator, so it might make sense to even create a mock of data when using the simulator.</li>
<li>Challenges – You can't programmatically issue GameKit Challenges to your friends anymore <a target="_blank" href="https://developer.apple.com/documentation/gamekit/gkscore/1520610-issuechallenge">due to deprecation</a>. Instead, you have to do those manually within the user's GameCenter dashboard against GameKit Achievements. Also, there's no way to view challenges you have sent. </li>
<li>Achievements – Leaderboards are different from the GameKit Achievements, which is calculated and displayed differently, but a <a target="_blank" href="https://github.com/StairMasterClimber/mobile/blob/18283a68e1c5cac4e270a85b03853887b3950156/StairStepperMaster/StairStepperMaster/Views/AchievementTileView.swift#L113">lot easier</a>. Those can also be pulled into the app as well, as you can see below:</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/Frame-2-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>GameKit Challenges and Achievements</em></p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>You can try out the free open-source <a target="_blank" href="https://stairmasterclimber.com/app">Stair Master Climber iPhone Health &amp; Fitness app</a> that I shared above. I would love to know what you think so that we can learn together. </p>
<p>Feel free to reach out to me on <a target="_blank" href="https://twitter.com/StairMasterApp">social media</a> or by <a target="_blank" href="mailto:hi@stairmasterclimber.com">email</a> if you have any questions.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use UISearchController in iOS Apps ]]>
                </title>
                <description>
                    <![CDATA[ By Sai Balaji K Hello everyone! In this article we are going to learn how to use UISearchController in iOS Apps. What are we going to build? We are going to build a movie search application which uses the TMDB API to fetch movie info and display it u... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-to-use-uisearchcontroller-in-ios-apps/</link>
                <guid isPermaLink="false">66d460c7b3016bf139028d85</guid>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ios app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Xcode ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 24 Mar 2022 15:55:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-21-at-8.11.31-PM.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sai Balaji K</p>
<p>Hello everyone! In this article we are going to learn how to use UISearchController in iOS Apps.</p>
<h2 id="heading-what-are-we-going-to-build">What are we going to build?</h2>
<p>We are going to build a movie search application which uses the <a target="_blank" href="https://www.themoviedb.org/">TMDB</a> API to fetch movie info and display it using a UICollectionView based on a user's search query.</p>
<h2 id="heading-project-setup">Project Setup</h2>
<p>Open up Xcode and create a new blank iOS App project – make sure you select UIKit and not SwiftUI.</p>
<p>In this app we are going to use the MVC Pattern so organise the project by creating the following groups and Swift files:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-21-at-8.16.02-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now close your Xcode project. Open up the terminal and move to your project directory. Here we need to add <a target="_blank" href="https://cocoapods.org/pods/SDWebImage">SD WebImage</a> Cocoa Pods to asynchronously download and cache the movie poster images.</p>
<p>Type the following command in the terminal:</p>
<pre><code>pod init
</code></pre><p>Now when you list the contents of the directory, you can see that there is a new Podfile. Open the file using any text editor (here I've used Vim). Edit your Podfile so that it looks similar to the below image. Save and close the Podfile.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-21-at-8.20.28-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now that we have specified the SD WebImage, we can install the dependencies by running the below command:</p>
<pre><code>pod install
</code></pre><p>As you can see, we have successfully added the SD WebImage pod in our iOS project. Now run the below command to open our project in Xcode.</p>
<pre><code>open PROJECT_NAME.xcworkspace
</code></pre><p>After opening Xcode, make sure you build your project by hitting Command+B.</p>
<h2 id="heading-how-to-design-the-user-interface-using-uikit-and-programmatic-ui"><strong>How to Design the User Interface using UIKit and Programmatic UI</strong></h2>
<p>Our app needs three UIElements navigation bars to hold the search bar, UISearchBarController for actual search, and a UICollectionView to display the search results.</p>
<p>Open up your Scenedelegate.swift file and add the following code inside it which will connect to the session method:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">scene</span><span class="hljs-params">(<span class="hljs-number">_</span> scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)</span></span> {
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> scene = (scene <span class="hljs-keyword">as</span>? <span class="hljs-type">UIWindowScene</span>) <span class="hljs-keyword">else</span> { <span class="hljs-keyword">return</span> }
        window = <span class="hljs-type">UIWindow</span>(windowScene: scene)       window?.rootViewController=<span class="hljs-type">UINavigationController</span>(rootViewController:<span class="hljs-type">HomeVC</span>())
        window?.makeKeyAndVisible()
    }
</code></pre>
<p>Since we are using a programatic UI, first we need to mention our Root View controller – that is, the first screen which will be displayed when the user launches the app. </p>
<p>Here in this app we're using only one View Controller, so we wrap it inside a UINavigationController. This provides a navigation bar where we can place our UISearchController.</p>
<p>Open up the HomeVC.swift file and add the following properties:</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> <span class="hljs-type">SearchBar</span>: <span class="hljs-type">UISearchController</span> = {
        <span class="hljs-keyword">let</span> sb = <span class="hljs-type">UISearchController</span>()
        sb.searchBar.placeholder = <span class="hljs-string">"Enter the movie name"</span>
        sb.searchBar.searchBarStyle = .minimal
        <span class="hljs-keyword">return</span> sb
    }()

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> <span class="hljs-type">MovieCollectionView</span>: <span class="hljs-type">UICollectionView</span> = {
        <span class="hljs-keyword">let</span> layout = <span class="hljs-type">UICollectionViewFlowLayout</span>()
        layout.scrollDirection = .vertical
        layout.itemSize = <span class="hljs-type">CGSize</span>(width: <span class="hljs-type">UIScreen</span>.main.bounds.width/<span class="hljs-number">3</span> - <span class="hljs-number">10</span>, height: <span class="hljs-number">200</span>)
        <span class="hljs-keyword">let</span> cv = <span class="hljs-type">UICollectionView</span>(frame: .zero, collectionViewLayout: layout)
        cv.register(<span class="hljs-type">MovieCell</span>.<span class="hljs-keyword">self</span>, forCellWithReuseIdentifier: <span class="hljs-type">MovieCell</span>.<span class="hljs-type">ID</span>)
        <span class="hljs-keyword">return</span> cv
    }()
</code></pre>
<p>First we create our UISearchController and configure its properties such as placeholder text and style. </p>
<p>Then we create a UICollectionView and specify the type of layout our collection view should use. In this case it is UICollectionViewFlowLayout and other properties such as scroll direction, item size, and specifying a custom CollectionView cell class which we will create later in our project.</p>
<p>Inside the HomeVC class create a new function and add the following code to configure auto-layout constraints programmatically for our UICollectionView:</p>
<pre><code class="lang-swift">    <span class="hljs-comment">//MARK: - HELPERS</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">configureUI</span><span class="hljs-params">()</span></span>{
        <span class="hljs-type">MovieCollectionView</span>.translatesAutoresizingMaskIntoConstraints = <span class="hljs-literal">false</span>
        <span class="hljs-type">MovieCollectionView</span>.topAnchor.constraint(equalTo: view.topAnchor).isActive = <span class="hljs-literal">true</span>
        <span class="hljs-type">MovieCollectionView</span>.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = <span class="hljs-literal">true</span>
        <span class="hljs-type">MovieCollectionView</span>.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = <span class="hljs-literal">true</span>
        <span class="hljs-type">MovieCollectionView</span>.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = <span class="hljs-literal">true</span>
    }
</code></pre>
<p>First we say that we don't need to convert the auto resizing mask into the constraints. Then we pin our collection view to all four sides of our View Controller.</p>
<p>Inside the <code>viewDidLoad()</code> method add the following lines of code:</p>
<pre><code class="lang-swift">  <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">viewDidLoad</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">super</span>.viewDidLoad()

        navigationItem.title  = <span class="hljs-string">"Movie Search"</span>
        view.backgroundColor = .systemBackground
        <span class="hljs-type">SearchBar</span>.searchResultsUpdater = <span class="hljs-keyword">self</span>
        navigationItem.searchController = <span class="hljs-type">SearchBar</span>
        view.addSubview(<span class="hljs-type">MovieCollectionView</span>)
        <span class="hljs-type">MovieCollectionView</span>.delegate = <span class="hljs-keyword">self</span>
        <span class="hljs-type">MovieCollectionView</span>.dataSource = <span class="hljs-keyword">self</span>
        configureUI()
    }
</code></pre>
<p>Here we first specify the title for our ViewController followed by the background color which is the systemBackground color. If the device is in light mode it shows a white background. If it is in dark mode, then it shows a dark background. </p>
<p>Then we set current the view controller as the search result updater, then add our SearchController to the navigation bar, add the UICollectionView to the ViewController, and setup delegate and datasource. Finally we pin the UICollectionView by using auto-layout.</p>
<p>Create an extension for HomeVC and implement the UISearchResultsUpdating protocol and its stub method updateSearchResults.</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">extension</span> <span class="hljs-title">HomeVC</span>: <span class="hljs-title">UISearchResultsUpdating</span></span>{

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">updateSearchResults</span><span class="hljs-params">(<span class="hljs-keyword">for</span> searchController: UISearchController)</span></span> {
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> query = searchController.searchBar.text <span class="hljs-keyword">else</span>{<span class="hljs-keyword">return</span>}

        }

    }


}
</code></pre>
<p>The <code>updateSearchResults()</code> method will be called whenever the text entered in the search bar changes or when the user taps the search button on their keyboard.</p>
<p>Next we need to create that custom UICollectionView cell. Inside the MovieCell.swift file, add the following code:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> Foundation
<span class="hljs-keyword">import</span> UIKit
<span class="hljs-keyword">import</span> SDWebImage

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MovieCell</span>: <span class="hljs-title">UICollectionViewCell</span></span>{

    <span class="hljs-keyword">static</span> <span class="hljs-keyword">let</span> <span class="hljs-type">ID</span> = <span class="hljs-string">"MovieCell"</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> <span class="hljs-type">MoviePosterImageView</span>: <span class="hljs-type">UIImageView</span> = {
        <span class="hljs-keyword">let</span> imageView = <span class="hljs-type">UIImageView</span>()
        imageView.contentMode = .scaleAspectFit
      <span class="hljs-comment">//  imageView.image = UIImage(systemName: "house")</span>
        <span class="hljs-keyword">return</span> imageView
    }()

    <span class="hljs-keyword">override</span> <span class="hljs-keyword">init</span>(frame: <span class="hljs-type">CGRect</span>) {
        <span class="hljs-keyword">super</span>.<span class="hljs-keyword">init</span>(frame: frame)
        addSubview(<span class="hljs-type">MoviePosterImageView</span>)
        configureUI()
    }

    <span class="hljs-keyword">required</span> <span class="hljs-keyword">init</span>?(coder: <span class="hljs-type">NSCoder</span>) {
        <span class="hljs-built_in">fatalError</span>(<span class="hljs-string">"init(coder:) has not been implemented"</span>)
    }

}

<span class="hljs-class"><span class="hljs-keyword">extension</span> <span class="hljs-title">MovieCell</span></span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">configureUI</span><span class="hljs-params">()</span></span>{
        <span class="hljs-type">MoviePosterImageView</span>.translatesAutoresizingMaskIntoConstraints = <span class="hljs-literal">false</span>
        <span class="hljs-type">MoviePosterImageView</span>.topAnchor.constraint(equalTo: topAnchor).isActive = <span class="hljs-literal">true</span>
        <span class="hljs-type">MoviePosterImageView</span>.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = <span class="hljs-literal">true</span>
        <span class="hljs-type">MoviePosterImageView</span>.leftAnchor.constraint(equalTo: leftAnchor).isActive = <span class="hljs-literal">true</span>
        <span class="hljs-type">MoviePosterImageView</span>.rightAnchor.constraint(equalTo: rightAnchor).isActive = <span class="hljs-literal">true</span>
    }
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">updateCell</span><span class="hljs-params">(posterURL: String?)</span></span>{
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> posterURL = posterURL {
            <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> <span class="hljs-type">CompleteURL</span> = <span class="hljs-type">URL</span>(string: <span class="hljs-string">"https://image.tmdb.org/t/p/w500/\(posterURL)"</span>) <span class="hljs-keyword">else</span> {<span class="hljs-keyword">return</span>}
            <span class="hljs-keyword">self</span>.<span class="hljs-type">MoviePosterImageView</span>.sd_setImage(with: <span class="hljs-type">CompleteURL</span>)
        }

    }
}
</code></pre>
<p>Here we create our custom collection view cell by sub-classing the UICollectionView class and implementing the <code>init()</code> functions. </p>
<p>We create a UIImageView to display the movie poster image and setup auto-layout constraints for it. Then we create a user defined function which takes the Movie poster URL string a parameter and downloads it asynchronously without affecting the UI Thread/Main thread. It does this by using the SD WebImage CocoaPod which we added earlier.</p>
<h2 id="heading-how-to-set-up-our-api">How to Set Up Our API</h2>
<p>Before moving on, you'll need to get your API key for the <a target="_blank" href="https://www.themoviedb.org/">TMDB</a> API by creating an account (it's free). We are going to use the Movie Search end point of the API which takes the API Key and movie name as parameters.</p>
<pre><code class="lang-url">https://api.themoviedb.org/3/search/movie?api_key=API_KEY_HERE&amp;query=batman
</code></pre>
<p>You can examine the API response by running it in Postman.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-22-at-8.52.57-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-create-a-model-for-the-api-response">How to Create a Model for the API Response</h2>
<p>Now we get a JSON response from the API. We need to decode them to Swift which we can do by creating a model struct that implements the Codable protocol.</p>
<p>WE can generate the model struct for our JSON response easily by using JSON to Swift websites. Here is the model code for the API response – you can just copy and paste it inside the Model.swift file:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> Foundation

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">TrendingTitleResponse</span>: <span class="hljs-title">Codable</span> </span>{
    <span class="hljs-keyword">let</span> results: [<span class="hljs-type">Title</span>]
}

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Title</span>: <span class="hljs-title">Codable</span> </span>{
    <span class="hljs-keyword">let</span> id: <span class="hljs-type">Int</span>
    <span class="hljs-keyword">let</span> media_type: <span class="hljs-type">String?</span>
    <span class="hljs-keyword">let</span> original_name: <span class="hljs-type">String?</span>
    <span class="hljs-keyword">let</span> original_title: <span class="hljs-type">String?</span>
    <span class="hljs-keyword">let</span> poster_path: <span class="hljs-type">String?</span>
    <span class="hljs-keyword">let</span> overview: <span class="hljs-type">String?</span>
    <span class="hljs-keyword">let</span> vote_count: <span class="hljs-type">Int</span>
    <span class="hljs-keyword">let</span> release_date: <span class="hljs-type">String?</span>
    <span class="hljs-keyword">let</span> vote_average: <span class="hljs-type">Double</span>
}

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">YoutubeSearchResponse</span>: <span class="hljs-title">Codable</span> </span>{
    <span class="hljs-keyword">let</span> items: [<span class="hljs-type">VideoElement</span>]
}


<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">VideoElement</span>: <span class="hljs-title">Codable</span> </span>{
    <span class="hljs-keyword">let</span> id: <span class="hljs-type">IdVideoElement</span>
}


<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">IdVideoElement</span>: <span class="hljs-title">Codable</span> </span>{
    <span class="hljs-keyword">let</span> kind: <span class="hljs-type">String</span>
    <span class="hljs-keyword">let</span> videoId: <span class="hljs-type">String</span>
}
</code></pre>
<h2 id="heading-how-to-perform-http-requests-using-swift">How to Perform  HTTP Requests Using Swift</h2>
<p>Now we need to write some Swift code to perform HTTP GET requests which return the JSON response of the API. </p>
<p>Swift provides a URLSession class which makes it easier to write networking code without needing any third party libraries like AFNetworking, AlamoFire, and so on.</p>
<p>Open APIService.swift and add the following code:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> Foundation

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">APIService</span></span>{
    <span class="hljs-keyword">static</span> <span class="hljs-keyword">var</span> shared = <span class="hljs-type">APIService</span>()
    <span class="hljs-keyword">let</span> session = <span class="hljs-type">URLSession</span>(configuration: .<span class="hljs-keyword">default</span>)

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getMovies</span><span class="hljs-params">(<span class="hljs-keyword">for</span> Query: String,completion:@escaping<span class="hljs-params">([Title]?,Error?)</span></span></span>-&gt;<span class="hljs-type">Void</span>){
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> <span class="hljs-type">FormatedQuery</span> = <span class="hljs-type">Query</span>.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)  <span class="hljs-keyword">else</span>{<span class="hljs-keyword">return</span>}

        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span>  <span class="hljs-type">SEARCH_URL</span> = <span class="hljs-type">URL</span>(string: <span class="hljs-string">"https://api.themoviedb.org/3/search/movie?api_key=API_KEY_HERE&amp;query=\(FormatedQuery)"</span>) <span class="hljs-keyword">else</span> {<span class="hljs-built_in">print</span>(<span class="hljs-string">"INVALID"</span>)
            <span class="hljs-keyword">return</span>}



        <span class="hljs-keyword">let</span> task = session.dataTask(with: <span class="hljs-type">SEARCH_URL</span>) { data, response, error <span class="hljs-keyword">in</span>
            <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> error = error {
                <span class="hljs-built_in">print</span>(error.localizedDescription)
                completion(<span class="hljs-literal">nil</span>,error)
            }
            <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> data = data {
                <span class="hljs-keyword">do</span>{
                    <span class="hljs-keyword">let</span> decodedData = <span class="hljs-keyword">try</span> <span class="hljs-type">JSONDecoder</span>().decode(<span class="hljs-type">TrendingTitleResponse</span>.<span class="hljs-keyword">self</span>, from: data)
                 <span class="hljs-comment">//   print(decodedData)</span>
                    completion(decodedData.results,<span class="hljs-literal">nil</span>)
                }
                <span class="hljs-keyword">catch</span>{
                    <span class="hljs-built_in">print</span>(error)
                }
            }
        }
        task.resume()
    }
}
</code></pre>
<p>Here we created a class named API Service with the singleton pattern so we need an instance for this class as a static member of the class. Then we created a session for our networking task with the default configuration, followed by a user defined method getMovies(). </p>
<p>Then we created our networking task – in this case we need to perform HTTP GET requests which can be performed using the <code>dataTask()</code> method of the URLSession class. It takes the URL as a parameter and gives a completion handler which contains data returned from the API, error data if any error has occurred, and a response which has HTTP Response information such as status codes and their corresponding messages. </p>
<p>If there is any error, then we escape out of this function with error data. If not, then we decode our JSON data based on our Swift Model and escape out of this function with the decoded data.</p>
<h2 id="heading-how-to-display-the-search-results-on-the-uicollectionview">How to Display the Search Results on the UICollectionView</h2>
<p>In HomeVC.swift, create a private property which is an array of Title objects. These will hold each movie's info returned by the API.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> <span class="hljs-type">Movies</span> = [<span class="hljs-type">Title</span>]()
</code></pre>
<p>In HomeVC.swift create an extension for the HomeVC class and implement the UIColletionViewDelegate and UICollectionViewDatasource protocols. Then implement numberOfItemsInSection (which is equal to the number of movies returned by the API) and cellForItemAt (which actually populates the cell with API responses, like download and set the poster image).</p>
<pre><code class="lang-swift"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, numberOfItemsInSection section: Int)</span></span> -&gt; <span class="hljs-type">Int</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-type">Movies</span>.<span class="hljs-built_in">count</span>
    }
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">UICollectionViewCell</span> {
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> cell = collectionView.dequeueReusableCell(withReuseIdentifier: <span class="hljs-type">MovieCell</span>.<span class="hljs-type">ID</span>, <span class="hljs-keyword">for</span>: indexPath) <span class="hljs-keyword">as</span>? <span class="hljs-type">MovieCell</span>{
           <span class="hljs-comment">// cell.backgroundColor = .systemBackground</span>

            cell.updateCell(posterURL: <span class="hljs-type">Movies</span>[indexPath.row].poster_path)
            <span class="hljs-keyword">return</span> cell
        }
        <span class="hljs-keyword">return</span> <span class="hljs-type">UICollectionViewCell</span>()

    }
</code></pre>
<p>Finally we need to make actual API call which we do inside the <code>updateSearchResults()</code> delegate method which we have implemented previously. Inside that method add the following code:</p>
<pre><code class="lang-swift">    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">updateSearchResults</span><span class="hljs-params">(<span class="hljs-keyword">for</span> searchController: UISearchController)</span></span> {
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> query = searchController.searchBar.text <span class="hljs-keyword">else</span>{<span class="hljs-keyword">return</span>}
        <span class="hljs-type">APIService</span>.shared.getMovies(<span class="hljs-keyword">for</span>:query.trimmingCharacters(<span class="hljs-keyword">in</span>: .whitespaces)) { titles, error <span class="hljs-keyword">in</span>
            <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> titles = titles {
                <span class="hljs-keyword">self</span>.<span class="hljs-type">Movies</span> = titles
                <span class="hljs-type">DispatchQueue</span>.main.async {
                    <span class="hljs-keyword">self</span>.<span class="hljs-type">MovieCollectionView</span>.reloadData()
                }

            }
        }

    }
</code></pre>
<p>Here, whenever the user types in the search bar or presses the search button, we make an HTTP GET request to fetch a movie (based on the name entered in the search bar). Then we reload the CollectionView which updates the collection view cells with the movie poster. </p>
<p>Note that we need to do this in the Main Thread/UI Thread, because by default iOS automatically makes HTTP request in background thread. This means that we need to use UI/Main Thread to update our UI elements. </p>
<p>Now run your app in the simulator to see the result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/ezgif.com-gif-maker--3-.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Congratulations! You have learned to use UISearchController in iOS apps.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn iOS Development by Building a Netflix Clone ]]>
                </title>
                <description>
                    <![CDATA[ Swift is one of the main languages used for iOS development. What better way to learn how to build an iOS app than to recreate a popular app? We just published a 5-hour course on the freeCodeCamp.org YouTube channel that will teach you how to use Swi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-ios-development-by-building-a-netflix-clone/</link>
                <guid isPermaLink="false">66b20496712508eb16067887</guid>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Tue, 15 Feb 2022 22:02:32 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/02/maxresdefault-1.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Swift is one of the main languages used for iOS development. What better way to learn how to build an iOS app than to recreate a popular app?</p>
<p>We just published a 5-hour course on the freeCodeCamp.org YouTube channel that will teach you how to use Swift 5, UIKit, and Xcode to develop iOS apps by building a Netflix clone.</p>
<p>Amr created this course. Amr is an iOS developer who has created many popular tutorials.</p>
<p>In this course you will learn how to implement the MVVM design pattern and create the app from scratch in Xcode. The Netflix code will play videos using the YouTube API.</p>
<p>Here are the sections in this course:</p>
<ul>
<li>Introduction and App Demo</li>
<li>Creating new Xcode Project</li>
<li>Creating MainTabBarViewController</li>
<li>Setting HomeViewController TableView</li>
<li>Setting home TableViewCell and it’s CollectionView</li>
<li>Creating Table’s HeaderView</li>
<li>Customizing the navigation bar</li>
<li>Setting Tableview sections titles</li>
<li>Sending URL Requests and Parsing JSON response</li>
<li>Using Extensions</li>
<li>Consuming API To Fetch Data for each Section</li>
<li>Refactoring Models</li>
<li>Creating Custom CollectionViewCell</li>
<li>Passing data to the CollectionView </li>
<li>Viewing poster images inside CollectionViewCell</li>
<li>Creating Upcoming TableView inside Upcoming Tab</li>
<li>Creating custom TableViewCell from the upcoming table</li>
<li>Creating TitleViewModel</li>
<li>Creating Top Search TableView inside TopSearch tab</li>
<li>Creating SearchResultsViewController to display search results</li>
<li>Querying database for individual movie</li>
<li>Using YouTube API</li>
<li>Parsing YouTube API Response</li>
<li>Handling selections of cells (Tapping on cells)</li>
<li>Creating TitlePreviewViewController</li>
<li>Refactoring TableViewHeader Hero title</li>
<li>Handling Tapping across all ViewControllers</li>
<li>Core Data (Best Practices)</li>
<li>Using Notification Center to update ViewControllers</li>
</ul>
<p>Watch the full course below or on <a target="_blank" href="https://youtu.be/KCgYDCKqato">the freeCodeCamp.org YouTube channel</a> (5-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/KCgYDCKqato" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Make a Simple Async GET REST API call in SwiftUI ]]>
                </title>
                <description>
                    <![CDATA[ By Saamer Mansoor In this tutorial for beginners, you will learn the basics of using SwiftUI to make API calls using the popular Internet Chuck Norris DataBase (ICNDB) as an example. It will display a joke quickly and easily using Swift and SwiftUI. ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/make-rest-api-call-in-swiftui-in-2-minutes/</link>
                <guid isPermaLink="false">66d460c7d7a4e35e384349ab</guid>
                
                    <category>
                        <![CDATA[ Apple ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SwiftUI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 02 Dec 2021 18:32:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/Frame-12-3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Saamer Mansoor</p>
<p>In this tutorial for beginners, you will learn the basics of using SwiftUI to make API calls using the popular Internet Chuck Norris DataBase (ICNDB) as an example. It will display a joke quickly and easily using Swift and SwiftUI. </p>
<p>You'll see how the cross-platform framework SwiftUI lets us use the exact same code across iOS, iPadOS, macOS, watchOS, App Clips and tvOS, which otherwise would have been impossible.</p>
<p>Along with that, you will use <a target="_blank" href="https://developer.apple.com/documentation/swift/swift_standard_library/concurrency/updating_an_app_to_use_swift_concurrency">async-await</a> that was introduced in Swift 5.5, which works for newer operating systems including iPhones running iOS &gt; v15.0. This really simplifies our work of making data network calls asynchronously on click of a button without freezing the UI thread. </p>
<p>I will share the code changes you'll need to make first. Then in the following section, I will share a brief analysis of the code so beginners can understand what's going on as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Group-1-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>tvOS app running the code displays a button that retrieves the joke on click</em></p>
<h2 id="heading-how-to-make-api-calls-in-swift-and-swiftui">How to Make API Calls in Swift and SwiftUI</h2>
<p>First, you'll need a Mac to install Xcode. Once it's installed, open Xcode and create a new project. Then select "App" for iOS, macOS, tvOS, or watchOS.</p>
<h3 id="heading-contentview">ContentView</h3>
<p>Just update your existing ContentView SwiftUI file to add a Button and use the <em>State</em> variable to refresh the text displayed as the joke returns from ICNDB API:</p>
<pre><code class="lang-swiftui">import Foundation
import SwiftUI
struct ContentView: View {
    @State private var joke: String = ""
    var body: some View {
        Text(joke)
        Button {
            Task {
                let (data, _) = try await URLSession.shared.data(from: URL(string:"https://api.chucknorris.io/jokes/random")!)
                let decodedResponse = try? JSONDecoder().decode(Joke.self, from: data)
                joke = decodedResponse?.value ?? ""
            }
        } label: {
            Text("Fetch Joke")
        }
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
struct Joke: Codable {
    let value: String
}
</code></pre>
<h3 id="heading-fetch-a-joke">Fetch a joke!</h3>
<p>If you press build/play, the app will build in whatever platform you selected above:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-01-at-4.42.11-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshots of watchOS, macOS, and iOS apps running the same exact code</em></p>
<h2 id="heading-code-analysis">Code Analysis</h2>
<p>If you go to the random joke URL, you'll notice that the data is in JSON format. You can copy that and use a JSON Linter to view its structure to figure out what property of the Joke object is needed. </p>
<p>Based on that, you determine the code above. You use the Codable protocol (aka interfaces) to go from a JSON data object to an actual Swift class or struct, and you create properties for the data you want to store (value in our case). </p>
<p>JSONDecoder helps us parse the JSON string using the Codable object. This works regardless of platform because the page that loads on launching the app has the same name <em>ContentView</em> regardless of platform.</p>
<h3 id="heading-app-clips">App Clips</h3>
<p><a target="_blank" href="https://developer.apple.com/app-clips/">App Clips</a> are Apple's latest way of using native app functionality using an "App Clip Code" without having to download the whole application from the App Store.</p>
<p>App Clips work similar to an iOS app – the only difference is that you don't create a new App Clip project. You just need to add the App Clip as a target to an existing iOS app by going to File-&gt;New-&gt;Target-&gt;iOS-&gt;App Clip when an existing iOS app is open in Xcode. </p>
<p>If you you wondering about iPhone/iPad <a target="_blank" href="https://support.apple.com/en-us/HT207122">Widgets</a>, well they don't animate. So button clicks will just open the corresponding app and can't update text through an external API independently. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you learned how to make RESTful GET API calls from SwiftUI in the simplest possible way! </p>
<p>Feel free to reach out to me if you have any questions. I figured this out using another article and I thought of simplifying it further. So for more details and ways to make this code more complex, check out that article:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.raywenderlich.com/25013447-async-await-in-swiftui">https://www.raywenderlich.com/25013447-async-await-in-swiftui</a></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Optional Types in Swift – How to Use and Unwrap Optionals ]]>
                </title>
                <description>
                    <![CDATA[ By Prajwal Kulkarni If you're coming from Java, C++, or other object-oriented languages, chances are that you've never come across optional types or "optionals". And you might be quite surprised to know that such a concept exists in Swift. Optionals ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/optional-types-in-swift/</link>
                <guid isPermaLink="false">66d4609333b83c4378a51824</guid>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 06 May 2021 16:06:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/05/maxwell-nelson-taiuG8CPKAQ-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Prajwal Kulkarni</p>
<p>If you're coming from Java, C++, or other object-oriented languages, chances are that you've never come across optional types or "optionals". And you might be quite surprised to know that such a concept exists in Swift.</p>
<p>Optionals are a fundamental topic that you need to thoroughly understand to code in Swift. If you're just getting started with Swift and you're learning about optional types for the first time, make sure to read this article until the end.</p>
<p>To understand what optional types are, let's quickly brush up on <strong>constants</strong> and <strong>variables.</strong></p>
<h2 id="heading-constants-and-variables-in-swift">Constants and Variables in Swift</h2>
<p>A constant is a data item whose value, once assigned, cannot be mutated (modified or changed) throughout the scope of the program. </p>
<p>On the other hand, a variable is a data item whose value can be changed limitlessly. </p>
<p>There are some nuances in how declare constants and variables in Swift. Let's look at that syntax:</p>
<p><code>&lt;data-item-type&gt; &lt;var-name&gt;:&lt;data-type&gt; = &lt;value&gt;</code></p>
<p><strong>Here's an example of a constant:</strong></p>
<p><code>let pi:Double = 3.1415</code></p>
<p><strong>And here's an example of a variable:</strong></p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> message:<span class="hljs-type">String</span> = <span class="hljs-string">"Hello, this is prajwal"</span>
message = <span class="hljs-string">"Coding in swift is awesome"</span> <span class="hljs-comment">//variable value changed.</span>
</code></pre>
<p>Notice that of the keywords we've used here for declaring constants and variables, you use <strong>let</strong> to declare a constant, and <strong>var</strong> to declare a variable.</p>
<p>The keyword is then followed by the constant/variable name, a colon and its data type, and then the assigning value.</p>
<p>Swift is a type-safety language, which means that you can assign variables and constants values without specifying the data type. It can make appropriate assumptions based on the assigned value, for example:</p>
<p><code>let const:String = "String"</code></p>
<p>can also be written as,</p>
<p><code>let const = "String"</code></p>
<p>And,</p>
<p><code>var speed:Int = 20</code></p>
<p>can be written as,</p>
<p><code>var speed = 35</code></p>
<p>You might be wondering, if you can omit the data type then what's the need to specify it anyway? Well, you're right to wonder that – but you need to specify the data type once you're working with optional types, which are different from conventional data types.</p>
<h2 id="heading-optional-types-or-optionals-in-swift">Optional types or Optionals in Swift</h2>
<p>Coming to the main point, what are optional types in Swift?</p>
<p>Let's see what the <a target="_blank" href="https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html">docs</a> have to say about it:</p>
<blockquote>
<p>You use optionals in situations where a value may be absent. An optional represents two possibilities: Either there is a value, and you can unwrap the optional to access that value, or there isn’t a value at all.</p>
</blockquote>
<p>That's a pretty straightforward definition. So optionals are basically used to handle null values at compile-time to ensure that no crashes occur at runtime.</p>
<p>Any operations on the optional variable are performed only if it contains non-null values.</p>
<p>An optional type can be of any data type, like a String, Integer, Double, Float, or any user defined non-primitive data type (object). </p>
<p>But, it is important to note that the Optional data type is not equivalent to its base data type. For instance, an Optional String is not the same as a string, an Optional integer is not the same as an integer, and so forth. This is because primitive data types cannot handle <code>nil</code> values, but Optional types can. </p>
<h2 id="heading-optional-types-syntax-and-usage-in-swift">Optional Types Syntax and Usage in Swift</h2>
<p>Here's the syntax for an optional type:</p>
<p><code>&lt;data-item&gt; &lt;var-name&gt;:&lt;data-type&gt;?</code></p>
<p>The declaration is similar to declaring regular variables, except that you add a question mark (?) beside the data type which makes it an Optional type.</p>
<p>Fire up your XCode playground and try running these snippets:</p>
<pre><code><span class="hljs-keyword">let</span> someVal:Double?
someVal = <span class="hljs-number">5.6324</span>

print(someVal)
<span class="hljs-comment">//Output : Optional(someVal)</span>

<span class="hljs-keyword">var</span> str:<span class="hljs-built_in">String</span>? = nil

str = <span class="hljs-string">"Hello, World!"</span>
print(str)
<span class="hljs-comment">//Output : Optional("Hello, World!")</span>
</code></pre><p>You can see that the outputs are not regular values. Instead, they're optional values.</p>
<h2 id="heading-how-to-unwrap-optional-types-in-swift">How to Unwrap Optional Types in Swift</h2>
<p>You won't use optional types upfront for any operations or tasks, as they should be cast in their primitives or user-defined instances before using it elsewhere (an optional string should be cast to a string, an optional integer should be cast to an integer, and so on). </p>
<p>This casting is what's known as <strong>unwrapping.</strong> You can better understand this concept by thinking about Schrödinger's cat. </p>
<p>In this thought experiment, a cat is placed in a closed box along with a vial of poison. Unless you open the box, you can't assure whether the cat is dead or alive ( nil or non-nil). This means that it is both dead and alive at the same time (nil and non-nil) according to your perception.</p>
<p>Only when you open the box (unwrapping) can you learn if the cat is alive or not (nil or not). </p>
<p>Unwrapping in Swift is essentially verifying if the Optional value is nil or not, and then it performs a task only if it's not nil.</p>
<p>You can perform unwrapping in the following ways:</p>
<ol>
    <li>Using an if else block</li>
    <li>Using Forced unwrapping</li>
    <li>Using Optional binding</li>
    <li>Using Optional chaining</li>
    <li>Using a nil coalescing operator</li>
</ol>

<h3 id="heading-unwrap-an-optional-type-with-an-if-else-block">Unwrap an optional type with an if-else block</h3>
<p>Unwrapping means to make sure that the Optional value is not nil. You can do this by using a simple if-else block like this:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> variable:<span class="hljs-type">String?</span> <span class="hljs-comment">//evaluates to nil</span>

<span class="hljs-keyword">if</span> variable != <span class="hljs-literal">nil</span>{
 <span class="hljs-built_in">print</span>(<span class="hljs-string">"Not nil"</span>)
}
<span class="hljs-keyword">else</span>{
 <span class="hljs-built_in">print</span>(<span class="hljs-string">"Nil"</span>)
}
<span class="hljs-comment">//Output : Nil</span>
</code></pre>
<h3 id="heading-unwrap-an-optional-type-with-forced-unwrapping">Unwrap an optional type with forced unwrapping</h3>
<p>Forced unwrapping is quite contradictory because you're accessing the optional value regardless of its value (nil or not nil). If a nil optional is unwrapped, an error is thrown saying "<strong>Unexpectedly found nil while unwrapping an Optional value</strong>." </p>
<p>You're supposed to use forced unwrapping only in a pre-defined environment where you're certain that the optional value won't be nil.</p>
<p>You can forcefully unwrap an optional using the exclamatory(!) operator like this:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> color:<span class="hljs-type">String?</span>;

<span class="hljs-built_in">print</span>(color!) <span class="hljs-comment">// Unexpectedly found nil while unwrapping an Optional value</span>

color = <span class="hljs-string">"Black"</span>;

<span class="hljs-built_in">print</span>(color!) <span class="hljs-comment">// Black</span>
</code></pre>
<h3 id="heading-unwrap-an-optional-type-with-optional-binding">Unwrap an optional type with optional binding</h3>
<p>Optional binding is similar to using an if-else block. The only subtle difference is that if the optional value is not nil, the unwrapped value is assigned to a new constant and further operations are performed on the constant. </p>
<p>You can do this using the <strong>if-let</strong> statement:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> password:<span class="hljs-type">String?</span> = <span class="hljs-string">"$tr0ngp@$$w0rd"</span>

<span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> unwrappedpass = password {
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Password is \(unwrappedpass)"</span>) <span class="hljs-comment">//Password is $tr0ngp@$$w0rd</span>
}
</code></pre>
<p>An optional string <code>password</code> is assigned the value <code>$tr0ngp@$$w0rd</code>. Then in the if-let block, the optional value <code>password</code> is unwrapped and assigned to the variable <code>unwrappedpass</code> only if the optional value <code>password</code> is not nil. <code>unwrappedpass</code> now contains the unwrapped value and can be used within the block's scope.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> password:<span class="hljs-type">String?</span>

<span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> unwrap = password{ <span class="hljs-comment">// Block unexecuted, as optional password is nil.</span>
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"value is not nil"</span>)
}
</code></pre>
<h3 id="heading-unwrap-an-optional-type-with-optional-chaining">Unwrap an optional type with optional chaining</h3>
<p>You use optional chaining in places where you're dealing with multiple optional values at once. You use it to access and mutate or assign far-fetched attributes whose value depends on other constraints.</p>
<p>For example, we get our food from plants, which in turn get their food from sunlight and water.</p>
<p>This means that there is a chained dependency of events – we are dependent on plants for our food, and plants themselves are dependent on water and light for their food.</p>
<p>Optional chaining involves verifying at each dependency if the instance is nil or not.</p>
<p>Let's see how this works with a code example:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ShipmentCar</span></span>{
    <span class="hljs-keyword">var</span> seats:<span class="hljs-type">Int?</span>
    <span class="hljs-keyword">var</span> quality:<span class="hljs-type">String?</span>

    <span class="hljs-keyword">init</span>(seatQty:<span class="hljs-type">Int</span>){
        seats = seatQty
    }

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">displaySeatQuality</span><span class="hljs-params">()</span></span>{
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> seatQuality = quality{
            <span class="hljs-built_in">print</span>(<span class="hljs-string">"The seat covering is made of:\(seatQuality)"</span>)
        }
    }



}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CheckSeats</span></span>{
    <span class="hljs-keyword">var</span> seatExists:<span class="hljs-type">ShipmentCar?</span>

}


<span class="hljs-keyword">var</span> obj = <span class="hljs-type">ShipmentCar</span>(seatQty:<span class="hljs-number">4</span>)
<span class="hljs-keyword">var</span> obj2:<span class="hljs-type">CheckSeats?</span>
obj2 = <span class="hljs-type">CheckSeats</span>()
obj2?.seatExists = obj
obj2?.seatExists?.quality = <span class="hljs-string">"Leather"</span> <span class="hljs-comment">//Optional chaining, set leather quality of seats, only if seats exist.</span>
obj.displaySeatQuality()
<span class="hljs-comment">//Output: The seat covering is made of: Leather</span>
</code></pre>
<p>In the above example, we have two classes, <code>ShipmentCar</code> which is cargo, and <code>CheckSeats</code> to check if there are any seats in the vehicle.</p>
<p>We first create an instance of the class <code>ShipmentCar</code> and pass the argument as 4 for the number of seats – meaning that there are 4 seats in the vehicle. </p>
<p>Further, we create an optional instance of the class <code>CheckSeats</code> and instantiate it. The attribute <code>seatExists</code> of the class <code>CheckSeats</code> is of the type optional <code>ShipmentCar</code>. </p>
<p>Next, we perform optional chaining on the instance <code>obj2</code>, which we write as <code>obj2?.seatExists?.quality = "Leather"</code>. This means that we check if seats exist in the car, and if the seats exist, we define the quality of the seat cover which is <code>Leather</code>. Then we verify by calling the <code>displaySeatQuality</code> and get the desired result.</p>
<p><strong>Here's a small caveat</strong>: in the above example, if you set the value of <code>seatQty</code> as 0 instead of 4, it'd still output the same result. This implies that the seat covers are made of leather even though there are 0 seats, which would make no sense. </p>
<p>So, I'd like to mention that this is just an example and the main objective here is to emphasize that the attributes are assigned values only if the dependent attributes are not-nil.</p>
<h3 id="heading-unwrap-an-optional-type-with-the-nil-coalescing-operator">Unwrap an optional type with the nil coalescing operator</h3>
<p>The nil coalescing operator works as shorthand notation for the regular if-else block. If a nil value is found when an optional value is unwrapped, an additional default value is supplied which will be used instead.</p>
<pre><code><span class="hljs-keyword">var</span> text:<span class="hljs-built_in">String</span>?

<span class="hljs-keyword">var</span> output = text ?? <span class="hljs-string">"Default value"</span>

print(output) <span class="hljs-comment">// Default value</span>

text = <span class="hljs-string">"This is a string"</span>

output = text ?? <span class="hljs-string">"Default String"</span>

print(output) <span class="hljs-comment">// This is a string</span>
</code></pre><p>You can also write default values in terms of objects.</p>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>There you have it! In this article, you've learned all about optional types and how to use them.</p>
<p>I'd like to thank you for reading this far and I hope this article has helped you understand optional types in Swift.</p>
<p>If you've any queries, feel free to contact me on <a target="_blank" href="https://twitter.com/prajwalinbizz">Twitter</a> and/or <a target="_blank" href="https://www.linkedin.com/in/prajwal-kulkarni">LinkedIn</a>. I'll be happy to help you. Cheers!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add the Realm Database to an iOS CRUD App using Swift ]]>
                </title>
                <description>
                    <![CDATA[ By Sai Balaji K Hello, everyone! In this article we are going to learn how to add the Realm database to an iOS app.  We'll create a simple ToDo app so you can learn how to perform CRUD (Create, Read, Update, Delete) operations in the Realm database. ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/add-realm-database-to-ios-crud-app-with-with-swift/</link>
                <guid isPermaLink="false">66d460c5230dff0166905863</guid>
                
                    <category>
                        <![CDATA[ database ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ios app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 27 Apr 2021 18:21:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/605aa5a8687d62084bf6b611.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sai Balaji K</p>
<p>Hello, everyone! In this article we are going to learn how to add the Realm database to an iOS app. </p>
<p>We'll create a simple ToDo app so you can learn how to perform CRUD (Create, Read, Update, Delete) operations in the Realm database.</p>
<h2 id="heading-what-is-realm">What is Realm?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-24-at-8.09.31-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Realm is an open-source mobile database which is developer friendly and easy to use. You can also use it as an alternative to Core Data in iOS apps. </p>
<p>Realm is a cross platform mobile database, which means that you can use it in native Android and iOS apps and also in cross platform apps like those created using React Native. It supports Objective-C, Swift, Java, Kotlin, C#, and JavaScript.</p>
<h2 id="heading-how-to-set-up-realm-in-your-ios-project">How to Set Up Realm in Your iOS Project</h2>
<p>We can add Realm to our iOS project using SPM (the Swift Package Manager), Cocoa Pods, or Carthage. Here, we are going to use Cocoa Pods to add Realm Pod to our iOS project.</p>
<ol>
<li>Open up Xcode and create a blank iOS app project with UIKit and Swift without using Core Data.</li>
<li>Now close Xcode and open up the terminal. Navigate to your project directory using the terminal.</li>
<li>Run the following command to create a PodFile.</li>
</ol>
<pre><code class="lang-command">pod init
</code></pre>
<ol start="4">
<li>Now when you list the contents of the directory you can see that there is a new Podfile. Open the file using any text editor (here I've used Vim). Edit your Podfile so that it looks similar to the below image. Save and close the Podfile.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-24-at-8.23.07-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now that we have specified the dependence for Realm DB, we can install the dependencies by running the below command:</p>
<pre><code class="lang-command">pod install
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-24-at-8.26.21-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As you can see, we have successfully added the Realm DB dependency in our iOS project. Now run the below command to open our project in Xcode.</p>
<pre><code class="lang-command">open YOUR_APP_NAME.xcworkspace
</code></pre>
<p>Note: after opening Xcode, make sure you build your project by pressing Command+B.</p>
<h2 id="heading-how-to-design-your-user-interface-in-realm">How to Design Your User Interface in Realm</h2>
<p>We are going to keep our app's UI simple. Open up Main.storyboard and create a simple UI as shown below by adding a table view with a prototype cell. Then embed a navigation controller and create the IBOutlets for the tableview in the ViewController.swift file:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-24-at-8.32.42-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-create-a-data-model-in-realm">How to Create a Data Model in Realm</h2>
<p>In our ToDo app, each task has a task name and a task id. We are going to create a Model class to represent the todo task. In the project navigator right click and create a new Swift file, and add the below code.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> Foundation
<span class="hljs-keyword">import</span> RealmSwift


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ToDoTask</span>:<span class="hljs-title">Object</span>
</span>{
    <span class="hljs-meta">@objc</span> <span class="hljs-keyword">dynamic</span> <span class="hljs-keyword">var</span> tasknote: <span class="hljs-type">String?</span>
    <span class="hljs-meta">@objc</span> <span class="hljs-keyword">dynamic</span> <span class="hljs-keyword">var</span> taskid: <span class="hljs-type">String?</span>
}
</code></pre>
<p>Her we created our model class named ToDoTask. It inherits the Object class which is a class that comes with RealmDB. This class handles all the under the hood processes of saving the data created using this model class in the database.</p>
<p>We also added two properties: <code>tasknote</code>, which is the task to be done, and <code>taskid</code> – both of type string. <code>@objc</code> means that your Swift code is visible to Objective C and <code>dynamic</code> means you want to use Objective C dynamic dispatch.</p>
<h2 id="heading-basic-crud-app-functions">Basic CRUD App functions</h2>
<p>Our app will perform the following functions:</p>
<ol>
<li>Get input from the user using AlertViewController.</li>
<li>Add the input to the database and also to the table view.</li>
<li>Allow the user to edit their input.</li>
<li>Swipe to delete a row to remove the data from both the table view and the database.</li>
<li>Fetch all the data (if present) from the database and display it in the table view.</li>
</ol>
<h3 id="heading-how-to-get-input-from-the-user-using-alertviewcontroller">How to get input from the user using AlertViewController</h3>
<p>Open up <code>ViewController.swift</code> and add the below code inside the <code>ViewDidLoad()</code> method. And create a new function called <code>addTask()</code> and add the code to display the alert view controller with a text box to get input from the user. </p>
<p>Now when the right bar button is pressed it will call the <code>addTask()</code> function which will display the <code>alertviewcontroller</code> with a text field to get user input.</p>
<pre><code class="lang-swift">navigationItem.rightBarButtonItem = <span class="hljs-type">UIBarButtonItem</span>(image: .add, style: .done, target: <span class="hljs-keyword">self</span>, action: #selector(addTask))

navigationController?.navigationBar.prefersLargeTitles = <span class="hljs-literal">true</span>

title = <span class="hljs-string">"RealmDB"</span>
</code></pre>
<pre><code class="lang-swift"><span class="hljs-meta">@objc</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">addTask</span><span class="hljs-params">()</span></span>
    { 
        <span class="hljs-keyword">let</span> ac = <span class="hljs-type">UIAlertController</span>(title: <span class="hljs-string">"Add Note"</span>, message: <span class="hljs-literal">nil</span>, preferredStyle: .alert)

        ac.addTextField(configurationHandler: .<span class="hljs-keyword">none</span>)

        ac.addAction(<span class="hljs-type">UIAlertAction</span>(title: <span class="hljs-string">"Add"</span>, style: .<span class="hljs-keyword">default</span>, handler: { (<span class="hljs-type">UIAlertAction</span>) <span class="hljs-keyword">in</span>

              <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> text = ac.textFields?.first?.text
            {
                <span class="hljs-built_in">print</span>(text)
            }

        }))
        ac.addAction(<span class="hljs-type">UIAlertAction</span>(title: <span class="hljs-string">"Cancel"</span>, style: .cancel, handler: <span class="hljs-literal">nil</span>))
        present(ac, animated: <span class="hljs-literal">true</span>, completion: <span class="hljs-literal">nil</span>)
    }
</code></pre>
<h3 id="heading-how-to-add-the-input-to-the-database-and-table-view">How to add the input to the database and table view</h3>
<p>To save data into Realm, first we need obtain an instance for Realm through which we can access all the methods needed for CRUD operations. Create a property of type Realm in the <code>ViewController.swift</code> file and initialise it in the <code>viewDidLoad()</code> method.</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">var</span> realmDB: <span class="hljs-type">Realm!</span>
</code></pre>
<pre><code class="lang-swift"> <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">viewDidLoad</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">super</span>.viewDidLoad()

        navigationItem.rightBarButtonItem = <span class="hljs-type">UIBarButtonItem</span>(image: .add, style: .done, target: <span class="hljs-keyword">self</span>, action: #selector(addTask))
        navigationController?.navigationBar.prefersLargeTitles = <span class="hljs-literal">true</span>
        title = <span class="hljs-string">"RealmDB"</span>

        realmDB = <span class="hljs-keyword">try</span>! <span class="hljs-type">Realm</span>()

    }
</code></pre>
<p>Create an empty array of type our DataModel (ToDoTask). This array will hold all the tasks which need to be added to the table view and database. </p>
<p>Now inside the <code>addTask()</code> function modify the Add action closure so that it gets the user input and creates a random ID for that input. Then append it to our array and save it to the database.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> tasks = [<span class="hljs-type">ToDoTask</span>]()
</code></pre>
<pre><code class="lang-swift"> <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> text = ac.textFields?.first?.text
            {
                <span class="hljs-comment">//Add data to data model array</span>
                <span class="hljs-keyword">let</span> t = <span class="hljs-type">ToDoTask</span>()
                t.taskid = <span class="hljs-type">UUID</span>().uuidString
                t.tasknote = text
                <span class="hljs-keyword">self</span>.tasks.append(t)

                <span class="hljs-comment">//Add data to database</span>
                <span class="hljs-keyword">try</span>! <span class="hljs-keyword">self</span>.realmDB.write {
                    <span class="hljs-keyword">self</span>.realmDB.add(t)
                }
                <span class="hljs-comment">//Update table view UI</span>
                <span class="hljs-keyword">self</span>.tasktv.reloadData()
            }
</code></pre>
<p>Now when you run the app, the data will be saved in the database. But it will not show in table view because we have not implemented the delegate methods. </p>
<p>Make the ViewController class implement the <code>UITableViewDelegate</code> and <code>UITableViewDataSource</code> protocols and add the protocol stubs. </p>
<p>Now inside the <code>numberOfRowsInSection</code> method, return the count of our tasks array which gives the number of rows to be added to the table view. This is equal to the number of elements in tasks array.</p>
<pre><code class="lang-swift"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">tableView</span><span class="hljs-params">(<span class="hljs-number">_</span> tableView: UITableView, numberOfRowsInSection section: 
 Int)</span></span> -&gt; <span class="hljs-type">Int</span> 
 {
        <span class="hljs-keyword">return</span> tasks.<span class="hljs-built_in">count</span>;
 }
</code></pre>
<p>The next thing we need to do is specify the content in each row. We can do this using the <code>cellForRowAt</code> delegate method. Here we dequeue a cell using the identifier which we have mentioned in storyboard and specify the label text as the tasks array element tasknote property.</p>
<pre><code class="lang-swift"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">tableView</span><span class="hljs-params">(<span class="hljs-number">_</span> tableView: UITableView, cellForRowAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">UITableViewCell</span> {
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> cell = tableView.dequeueReusableCell(withIdentifier: <span class="hljs-string">"cell"</span>)
        {
            cell.textLabel?.text = tasks[indexPath.row].tasknote
            <span class="hljs-keyword">return</span> cell
        }
        <span class="hljs-keyword">return</span> <span class="hljs-type">UITableViewCell</span>()
    }
</code></pre>
<h3 id="heading-how-to-allow-users-to-edit-their-input">How to allow users to edit their input</h3>
<p>Now we have to allow the user to edit their entered tasks and update the changes in both the database and UI. We can do this using similar methods of getting input from the user. Implement the <code>didSelectRowAt</code> delegate method which will be called when user taps the table view row. </p>
<p>Add the below code which displays an <code>AlertViewController</code> with a text view. Then update the content of the cell with the entered text, and at the same time update the database contents.</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">tableView</span><span class="hljs-params">(<span class="hljs-number">_</span> tableView: UITableView, didSelectRowAt indexPath: IndexPath)</span></span> {

        <span class="hljs-keyword">let</span> tasktomodify = tasks[indexPath.row]
        <span class="hljs-keyword">let</span> ac = <span class="hljs-type">UIAlertController</span>(title: <span class="hljs-string">"Update task"</span>, message: <span class="hljs-literal">nil</span>, preferredStyle: .alert)

        ac.addTextField(configurationHandler: .<span class="hljs-keyword">none</span>)
        ac.addAction(<span class="hljs-type">UIAlertAction</span>(title: <span class="hljs-string">"Ok"</span>, style: .<span class="hljs-keyword">default</span>, handler: { (<span class="hljs-type">UIAlertAction</span>) <span class="hljs-keyword">in</span>
            <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> text = ac.textFields?.first?.text
            {
                <span class="hljs-keyword">if</span>(!text.isEmpty)
                {
                <span class="hljs-keyword">try</span>! <span class="hljs-keyword">self</span>.realmDB.write({
                    tasktomodify.tasknote = text
                })
                <span class="hljs-keyword">self</span>.tasktv.reloadData()
                }
            }
        }))

        present(ac, animated: <span class="hljs-literal">true</span>, completion: <span class="hljs-literal">nil</span>)
    }
</code></pre>
<h3 id="heading-how-to-swipe-to-delete-a-row-amp-remove-the-data-from-both-the-table-view-and-database">How to swipe to delete a row &amp; remove the data from both the table view and database</h3>
<p>Here we are going to implement a swipe to delete feature in our table view so that users can delete their tasks. But under the hood when the user swipe deletes a table view row then it should delete the data from database, data model array, and update the UI of the table view. </p>
<p>We can do this by implementing the <strong>commit editingStyle</strong> delegate method and adding the following code:</p>
<pre><code class="lang-swift"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">tableView</span><span class="hljs-params">(<span class="hljs-number">_</span> tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)</span></span> {
        <span class="hljs-keyword">if</span> editingStyle == .delete
        {
            <span class="hljs-keyword">let</span> tasktoDelete = tasks[indexPath.row]
            <span class="hljs-keyword">try</span>! realmDB.write({
                realmDB.delete(tasktoDelete)
                <span class="hljs-keyword">self</span>.tasks.remove(at: indexPath.row)
                <span class="hljs-keyword">self</span>.tasktv.deleteRows(at: [indexPath], with: .fade)
            })
        }
    }
</code></pre>
<h3 id="heading-how-to-fetch-all-the-data-if-present-from-the-database-and-display-it-in-the-table-view">How to fetch all the data (if present) from the database and display it in the table view</h3>
<p>Now we are going to implement our last operation, Read. Whenever the user launches the app, it should fetch data from the database (if data is present) and display it in the table view. </p>
<p>We can do this by creating a function <code>getTodo</code> in the view controller swift file and adding the following code inside it:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getTodos</span><span class="hljs-params">()</span></span>
    {
       <span class="hljs-comment">//Get all the data from the database</span>
        <span class="hljs-keyword">let</span> notes = realmDB.objects(<span class="hljs-type">ToDoTask</span>.<span class="hljs-keyword">self</span>)

        <span class="hljs-comment">//Clear the model data array to prevent duplicates</span>
        <span class="hljs-keyword">self</span>.tasks.removeAll()

        <span class="hljs-comment">/*If the fetched data is not empty then add it to model data array and update the UI */</span>
        <span class="hljs-keyword">if</span>(!notes.isEmpty)
        {
        <span class="hljs-keyword">for</span> n <span class="hljs-keyword">in</span> notes
        {

            <span class="hljs-keyword">self</span>.tasks.append(n)

        }
            <span class="hljs-keyword">self</span>.tasktv.reloadData()
        }


    }
</code></pre>
<h2 id="heading-bonus-tip-how-to-view-your-database-content-in-an-ios-simulator">Bonus Tip: How to View Your Database Content in an iOS Simulator</h2>
<p>Now when you run your app, you can see that it works as expected. But how can we check if the data is really stored in the database? We can use an app called MongoDB Realm Studio through which we can view our data stored in the Realm database of the simulator.</p>
<blockquote>
<p>Note that this method works only when you test the app using iOS simulator</p>
</blockquote>
<p>In the <code>viewDidLoad()</code> method, add the below line of code which will print the real file path of our app:</p>
<pre><code class="lang-swift"> <span class="hljs-built_in">print</span>(realmDB.configuration.fileURL!)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-24-at-9.48.59-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now copy the file path printed in the console, open up the terminal, and run the following command:</p>
<pre><code class="lang-command">open REALM_FILE_PATH_HERE
</code></pre>
<blockquote>
<p>Make sure you have downloaded MongoDB Realm Studio from the browser before running the above command.</p>
</blockquote>
<p>Now it will open the RealmFile of the app in MongoDB Realm Studio. This will display the data stored in the database in a table format. </p>
<p>If you make changes to your data by editing or deleting the task, the changes will be reflected in the MongoDB Realm Studio app:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot-2021-03-24-at-9.55.29-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Congratulations! You have made a simple app which implements CRUD operations in iOS apps.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to programmatically build a Spotify clone for iOS using AutoLayout: adding photos and updating the UI ]]>
                </title>
                <description>
                    <![CDATA[ By Said Hayani This is the second part of an article on building a Spotify UI clone with autoLayout programmatically. If you missed the first part, no worries - just please go and check it now.  In this article, we are going to add some mocked pictur... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-spotify-clone-for-ios-with-autolayout-programmatically-part-2/</link>
                <guid isPermaLink="false">66d460d2868774922c885008</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ autolayout ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS13 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iphone ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tutorial ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 10 Dec 2019 03:44:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/12/featured_image-4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Said Hayani</p>
<p>This is the second part of an article on building a Spotify UI clone with autoLayout programmatically. If you missed the first part, no worries - just please go and <a target="_blank" href="https://www.freecodecamp.org/news/autolayout-programmatically-spotify-clone-in-swift/">check it now</a>. </p>
<p>In this article, we are going to add some mocked pictures and try to make the UI look the same as Spotify's.</p>
<p>This is what we are going to do today ?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/Screen-Shot-2019-12-09-at-9.55.19-PM-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is were we left off in the first part:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/complet-layout-demo1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The next step is to create customized cells. So let's start by creating one with the name  <code>SubCustomCell</code>.</p>
<p>First, create a new Swift file inside the project folder and name it <code>SubCustomCell.swift</code>. This file will contain our custom cell that will represent the Playlist. After creating the file, try to add in the code below and initialize the cell, maybe with <code>backgroundColor</code>,  to see the UI changes when we register the cell with the <code>collectionView</code>. </p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> UIKit

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SubCustomCell</span>: <span class="hljs-title">UICollectionViewCell</span> </span>{
        <span class="hljs-keyword">override</span> <span class="hljs-keyword">init</span>(frame: <span class="hljs-type">CGRect</span>) {
        <span class="hljs-keyword">super</span>.<span class="hljs-keyword">init</span>(frame: frame)
        backgroundColor = .red
    }

    <span class="hljs-keyword">required</span> <span class="hljs-keyword">init</span>?(coder aDecoder: <span class="hljs-type">NSCoder</span>) {
        <span class="hljs-built_in">fatalError</span>(<span class="hljs-string">"init(coder:) has not been implemented"</span>)
    }
}
</code></pre>
<p>Then we register the <code>SubCustomCell</code>  inside <code>CustomCell.swift</code> within the <code>init</code> block. Replace <code>UICollectionViewCell.self</code> with  <code>SubCustomCell</code> like below.</p>
<pre><code class="lang-swift"> collectionView.register(<span class="hljs-type">SubCustomCell</span>.<span class="hljs-keyword">self</span>, forCellWithReuseIdentifier: cellId)
</code></pre>
<p>Also we need to make a modification on the <code>cellForItemAt</code> method and make it conform to  <code>SubCustomCell</code> like the following.</p>
<pre><code class="lang-swift"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">UICollectionViewCell</span> {
        <span class="hljs-keyword">let</span> cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, <span class="hljs-keyword">for</span>: indexPath) <span class="hljs-keyword">as</span>! <span class="hljs-type">SubCustomCell</span>
        <span class="hljs-comment">// cell.backgroundColor = .yellow</span>

        <span class="hljs-keyword">return</span> cell
    }
</code></pre>
<p>You should see the <code>backgroundColor</code> changed to <code>red</code> .</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/Screen-Shot-2019-12-03-at-1.10.25-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Swift CustomCell</em></p>
<p>Up until this point everything should be straightforward and clear.</p>
<p>Now we're going to fill the cells with some mocked pictures and create an <code>ImageView</code> inside each cell. I already downloaded some random pictures from <a target="_blank" href="https://www.pexels.com/">pexels.com,</a> but feel free to use any pictures you like (including these). You can find them in the <a target="_blank" href="https://github.com/hayanisaid/autoLayout-programmatically-in-swift">project files on Github</a>.</p>
<p>Let's create the <code>UIImageView</code> inside <code>SubCustomCell.swift</code> and make some constraints.</p>
<pre><code class="lang-swift">    <span class="hljs-keyword">let</span> <span class="hljs-type">ImageView</span> : <span class="hljs-type">UIImageView</span> = {
       <span class="hljs-keyword">let</span> iv = <span class="hljs-type">UIImageView</span>()
        iv.backgroundColor = .yellow
        <span class="hljs-keyword">return</span> iv

    }()
</code></pre>
<p>And add it to the <code>view</code> within the <code>init</code> block using <code>addSubView</code>.</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">override</span> <span class="hljs-keyword">init</span>(frame: <span class="hljs-type">CGRect</span>) {
        <span class="hljs-keyword">super</span>.<span class="hljs-keyword">init</span>(frame: frame)
        addSubview(<span class="hljs-type">ImageView</span>)

    }
</code></pre>
<p>Now let's make the <code>ImageView</code> take up all the space within the cell with the constraints below.</p>
<pre><code class="lang-swift"> <span class="hljs-type">ImageView</span>.translatesAutoresizingMaskIntoConstraints = <span class="hljs-literal">false</span>
            <span class="hljs-type">ImageView</span>.topAnchor.constraint(equalTo: topAnchor).isActive = <span class="hljs-literal">true</span>
            <span class="hljs-type">ImageView</span>.leftAnchor.constraint(equalTo: leftAnchor).isActive = <span class="hljs-literal">true</span>
            <span class="hljs-type">ImageView</span>.rightAnchor.constraint(equalTo: rightAnchor).isActive = <span class="hljs-literal">true</span>
            <span class="hljs-type">ImageView</span>.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = <span class="hljs-literal">true</span>
</code></pre>
<ul>
<li><code>LeftAnchor</code> represents the left anchor of the cell</li>
<li><code>rightAnchor</code> represents the right anchor of the cell</li>
<li><code>bottomAnchor</code> represents the bottom anchor of the cell </li>
<li><code>topAnchor</code> represents the top anchor of the cell</li>
</ul>
<p>And by making <code>ImageView</code> 's top anchor equal to the cell's top anchor (and doing the same for <code>ImageView</code> 's left, right, and bottom anchor) it makes the <code>ImageView</code> take up all the space of the <code>SubCustomCell</code> (cell).</p>
<p>Note: first you need to use <code>translatesAutoresizingMaskIntoConstraints</code> to be able to apply the constraints to the elements. Also don't forget to call <code>isActive</code> property and assign it to <code>true</code> – without doing that the constraints won't work and nothing will change.</p>
<p>The <code>ImageView</code> should have an image, so let's add one.</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">let</span> <span class="hljs-type">ImageView</span> : <span class="hljs-type">UIImageView</span> = {
       <span class="hljs-keyword">let</span> iv = <span class="hljs-type">UIImageView</span>()
        iv.backgroundColor = .yellow
        <span class="hljs-comment">// we have &gt;image1&lt; file inside the project </span>
        iv.image = <span class="hljs-type">UIImage</span>(named: <span class="hljs-string">"image1"</span>)
        iv.contentMode = .scaleAspectFill
        iv.clipsToBounds = <span class="hljs-literal">true</span>

        <span class="hljs-keyword">return</span> iv

    }()
</code></pre>
<p>And if you build and run the app, you should see the results and picture we added to the <code>SubCustomCell</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/Screen-Shot-2019-12-03-at-1.37.51-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Cool ?. Now there is an element we should add to the <code>SubCustomCell</code> to finish up. We need a title that will represent the title of the playlist:  <code>UILabel</code>.</p>
<p>For the title it will be like this:</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">let</span> <span class="hljs-type">TitleLabel</span> : <span class="hljs-type">UILabel</span> = {
        <span class="hljs-keyword">let</span> lb = <span class="hljs-type">UILabel</span>()
        lb.textColor = <span class="hljs-type">UIColor</span>.lightGray
        lb.font = <span class="hljs-type">UIFont</span>.systemFont(ofSize: <span class="hljs-number">16</span>)
        lb.font = <span class="hljs-type">UIFont</span>.boldSystemFont(ofSize: <span class="hljs-number">20</span>)
        lb.text = <span class="hljs-string">"Evening Music"</span>

        <span class="hljs-keyword">return</span> lb
    }()
</code></pre>
<p>I just put some random text there – you can put whatever you like. The next step is to add the element to the view and give it some constraints. The title will be placed at the bottom of the <code>ImageView</code>.</p>
<h3 id="heading-add-to-view">Add to view:</h3>
<pre><code class="lang-swift">addSubview(<span class="hljs-type">TitleLabel</span>)
</code></pre>
<h3 id="heading-applying-the-constraints-for-both-the-imageview-and-the-titlelabel">Applying the constraints for both the <code>ImageView</code> and the <code>TitleLabel</code></h3>
<pre><code class="lang-swift"> <span class="hljs-type">ImageView</span>.translatesAutoresizingMaskIntoConstraints = <span class="hljs-literal">false</span>
            <span class="hljs-type">ImageView</span>.topAnchor.constraint(equalTo: topAnchor).isActive = <span class="hljs-literal">true</span>
            <span class="hljs-type">ImageView</span>.leftAnchor.constraint(equalTo: leftAnchor).isActive = <span class="hljs-literal">true</span>
            <span class="hljs-type">ImageView</span>.rightAnchor.constraint(equalTo: rightAnchor).isActive = <span class="hljs-literal">true</span>
            <span class="hljs-type">ImageView</span>.heightAnchor.constraint(equalToConstant: <span class="hljs-number">240</span>).isActive = <span class="hljs-literal">true</span>
            <span class="hljs-type">ImageView</span>.bottomAnchor.constraint(equalTo: <span class="hljs-type">TitleLabel</span>.topAnchor).isActive = <span class="hljs-literal">true</span>



            <span class="hljs-type">TitleLabel</span>.translatesAutoresizingMaskIntoConstraints = <span class="hljs-literal">false</span>
            <span class="hljs-type">TitleLabel</span>.topAnchor.constraint(equalTo: <span class="hljs-type">ImageView</span>.bottomAnchor,constant: <span class="hljs-number">10</span>).isActive = <span class="hljs-literal">true</span>
            <span class="hljs-type">TitleLabel</span>.leftAnchor.constraint(equalTo: leftAnchor, constant: <span class="hljs-number">5</span>).isActive = <span class="hljs-literal">true</span>
            <span class="hljs-type">TitleLabel</span>.rightAnchor.constraint(equalTo: rightAnchor, constant: -<span class="hljs-number">5</span>).isActive = <span class="hljs-literal">true</span>
</code></pre>
<p>And here we go!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/Screen-Shot-2019-12-06-at-1.45.10-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We made the picture take up most of the space in the cell, and the rest is taken up by the title. As you can see, you can scroll horizontally in each section and also vertically in the entire screen.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/demo2.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now we are put some mock data into the cells to make it feel like it's real. For that I created a <code>JSON</code> file that contains some random data for sections and playlists.</p>
<p>First let's create a two structs, <code>Section</code> and <code>Playlist</code> . We create a separate file for each struct. </p>
<p> <code>section.swift</code> </p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> Foundation
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Section</span> </span>{
    <span class="hljs-keyword">var</span> title : <span class="hljs-type">String</span>
    <span class="hljs-keyword">var</span> playlists : <span class="hljs-type">NSArray</span>
    <span class="hljs-keyword">init</span>(dictionary:[<span class="hljs-type">String</span> : <span class="hljs-type">Any</span>]) {
        <span class="hljs-keyword">self</span>.title = dictionary[<span class="hljs-string">"title"</span>] <span class="hljs-keyword">as</span>? <span class="hljs-type">String</span> ?? <span class="hljs-string">""</span>
        <span class="hljs-keyword">self</span>.playlists = dictionary[<span class="hljs-string">"playlists"</span>] <span class="hljs-keyword">as</span>? <span class="hljs-type">NSArray</span> ?? []

}
}
</code></pre>
<p><code>playlist.swift</code></p>
<pre><code class="lang-swift"><span class="hljs-comment">//</span>
<span class="hljs-comment">//  playlist.swift</span>
<span class="hljs-comment">//  spotifyAutoLayout</span>
<span class="hljs-comment">//</span>
<span class="hljs-comment">//  Created by admin on 12/6/19.</span>
<span class="hljs-comment">//  Copyright © 2019 Said Hayani. All rights reserved.</span>
<span class="hljs-comment">//</span>

<span class="hljs-keyword">import</span> Foundation
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">PlayList</span> </span>{
    <span class="hljs-keyword">var</span> title: <span class="hljs-type">String</span>
    <span class="hljs-keyword">var</span> image : <span class="hljs-type">String</span>
    <span class="hljs-keyword">init</span>(dictionary : [<span class="hljs-type">String</span> : <span class="hljs-type">Any</span>]) {
        <span class="hljs-keyword">self</span>.title = dictionary[<span class="hljs-string">"title"</span>] <span class="hljs-keyword">as</span>? <span class="hljs-type">String</span> ?? <span class="hljs-string">""</span>
        <span class="hljs-keyword">self</span>.image = dictionary[<span class="hljs-string">"image"</span>] <span class="hljs-keyword">as</span>? <span class="hljs-type">String</span> ?? <span class="hljs-string">""</span>
    }

}
</code></pre>
<p>And then inside <code>ViewController.swift</code> we create a function that fetches the JSON for us and stores the results in an array.</p>
<pre><code class="lang-swift">
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"attempt to fetch Json"</span>)
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> path = <span class="hljs-type">Bundle</span>.main.path(forResource: <span class="hljs-string">"test"</span>, ofType: <span class="hljs-string">"json"</span>) {
            <span class="hljs-keyword">do</span> {
                  <span class="hljs-keyword">let</span> data = <span class="hljs-keyword">try</span> <span class="hljs-type">Data</span>(contentsOf: <span class="hljs-type">URL</span>(fileURLWithPath: path), options: .mappedIfSafe)
                  <span class="hljs-keyword">let</span> jsonResult = <span class="hljs-keyword">try</span> <span class="hljs-type">JSONSerialization</span>.jsonObject(with: data, options: .mutableLeaves)
                <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> jsonResult = jsonResult <span class="hljs-keyword">as</span>? [ <span class="hljs-type">Any</span>] {
                            <span class="hljs-comment">// do stuff</span>
                    jsonResult.forEach { (item) <span class="hljs-keyword">in</span>

                        <span class="hljs-keyword">let</span> section = <span class="hljs-type">Section</span>(dictionary: item <span class="hljs-keyword">as</span>! [<span class="hljs-type">String</span> : <span class="hljs-type">Any</span>])
                       <span class="hljs-comment">// print("FEtching",section.playlists)</span>
                        <span class="hljs-keyword">self</span>.sections.append(section)
                    }


                  <span class="hljs-keyword">self</span>.collectionView.reloadData()
                  }
              } <span class="hljs-keyword">catch</span> {
                   <span class="hljs-comment">// handle error</span>
              }
        }
    }
</code></pre>
<p>The <code>fetchJson</code> function is called within the <code>ViewDidLoad</code> method. We also have a variable called <code>sections</code> where we store the results:</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">var</span> sections = [<span class="hljs-type">Section</span>]()
</code></pre>
<p>The next step is to pass the data from <code>ViewController</code> to <code>CustomCell</code>. For that we create a variable inside <code>CustomCell</code> which will receive the data for each section: </p>
<pre><code class="lang-swift"> <span class="hljs-keyword">var</span> section : <span class="hljs-type">Section?</span>{
        <span class="hljs-keyword">didSet</span>{
            <span class="hljs-built_in">print</span>(<span class="hljs-string">"section ✅"</span>,<span class="hljs-keyword">self</span>.section)
        }
    }
</code></pre>
<p>We use <code>cellForItemAt</code>  inside the <code>ViewController</code> method to pass the data directly to the <code>CustomCell</code> .</p>
<pre><code class="lang-swift"><span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">UICollectionViewCell</span> {
        <span class="hljs-keyword">let</span> cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, <span class="hljs-keyword">for</span>: indexPath) <span class="hljs-keyword">as</span>! <span class="hljs-type">CustomCell</span>

        cell.section = sections[indexPath.item]

        <span class="hljs-keyword">return</span> cell
    }
</code></pre>
<p>Note: we always call <strong><code>self</code></strong><code>.collectionView.reloadData()</code> every-time <code>fetchJson</code> is called so the block below, inside <code>CustomCell</code>, will be called as well. Check the console, <code>shift</code> + command + C:</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">var</span> section : <span class="hljs-type">Section?</span> {
        <span class="hljs-keyword">didSet</span>{
            <span class="hljs-built_in">print</span>(<span class="hljs-string">"section ✅"</span>,<span class="hljs-keyword">self</span>.section)
        }
    }
</code></pre>
<p>The first thing we change is to set the the section title:</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">var</span> section : <span class="hljs-type">Section?</span> {
        <span class="hljs-keyword">didSet</span>{
            <span class="hljs-built_in">print</span>(<span class="hljs-string">"section ✅"</span>,<span class="hljs-keyword">self</span>.section)
            <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> section = <span class="hljs-keyword">self</span>.section <span class="hljs-keyword">else</span> {<span class="hljs-keyword">return</span>}
            <span class="hljs-keyword">self</span>.titleLabel.text = section.title
        }
    }
</code></pre>
<p>And then you should see that each section has a specific title on the screen ?.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/Screen-Shot-2019-12-06-at-3.23.32-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now it's time to pass the data down to <code>SubCustomCell</code>. We do the same thing as we did above. We need to pass the <code>playlists</code> array, so we create a variable named <code>playlists</code> inside <code>CustomCell</code>.</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">var</span> playlists : [<span class="hljs-type">PlayList</span>]() <span class="hljs-comment">//empty</span>
</code></pre>
<p>First, we map through the <code>playlists</code>  from the <code>JSON</code>. Then we add each playlist with the <code>playlists</code> var.</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">var</span> section : <span class="hljs-type">Section?</span> {
        <span class="hljs-keyword">didSet</span>{
            <span class="hljs-built_in">print</span>(<span class="hljs-string">"section ✅"</span>,<span class="hljs-keyword">self</span>.section)
            <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> section = <span class="hljs-keyword">self</span>.section <span class="hljs-keyword">else</span> {<span class="hljs-keyword">return</span>}
            <span class="hljs-keyword">self</span>.titleLabel.text = section.title
            <span class="hljs-comment">// append to playlists array</span>
             <span class="hljs-keyword">self</span>.section?.playlists.forEach({ (item) <span class="hljs-keyword">in</span>
                <span class="hljs-keyword">let</span> playlist = <span class="hljs-type">PlayList</span>(dictionary: item <span class="hljs-keyword">as</span>! [<span class="hljs-type">String</span> : <span class="hljs-type">Any</span>])
                <span class="hljs-keyword">self</span>.playlists.append(playlist)

            })
            <span class="hljs-keyword">self</span>.collectionView.reloadData()
        }
    }
</code></pre>
<p>Attention! If you try to run the app it may crash. This is because we forgot to set the number of sections. Since we are now receiving the data from JSON, the number should be dynamic based on the number of sections we have. The number of sections should be equal to the number of sections inside the <code>JSON</code>, so we need to modify <code>numberOfItemsInSection</code> inside <code>ViewController</code> to the below :</p>
<pre><code class="lang-swift">   <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, numberOfItemsInSection section: Int)</span></span> -&gt; <span class="hljs-type">Int</span> {
        <span class="hljs-keyword">return</span> sections.<span class="hljs-built_in">count</span>
    }
</code></pre>
<p>We do the same thing with the same method inside <code>CustomCell.swift</code> – but here we consider the number of the <code>playlists</code> instead.</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, numberOfItemsInSection section: Int)</span></span> -&gt; <span class="hljs-type">Int</span> {
        <span class="hljs-keyword">return</span>  <span class="hljs-keyword">self</span>.playlists.<span class="hljs-built_in">count</span>
    }
</code></pre>
<p>The last step we have to complete is to pass each single playlist <code>Object</code> to <code>SubCustomCell</code> within <code>cellForItemAt</code> in <code>CustomCell.swift</code>. </p>
<pre><code class="lang-swift"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">UICollectionViewCell</span> {
        <span class="hljs-keyword">let</span> cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, <span class="hljs-keyword">for</span>: indexPath) <span class="hljs-keyword">as</span>! <span class="hljs-type">SubCustomCell</span>
        <span class="hljs-comment">// here ?</span>
        cell.playlist = playlists[indexPath.item]
        <span class="hljs-keyword">return</span> cell
    }
</code></pre>
<p>And we are going to get that data inside <code>SubCustomCell</code> via the <code>playlist</code> variable and finally display the title and image of the playlist.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> playlist : <span class="hljs-type">PlayList?</span> {
           <span class="hljs-keyword">didSet</span>{
               <span class="hljs-built_in">print</span>(<span class="hljs-string">"Playlist ?"</span>,<span class="hljs-keyword">self</span>.playlist)
            <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> playlist = <span class="hljs-keyword">self</span>.playlist <span class="hljs-keyword">else</span> {<span class="hljs-keyword">return</span>}
            <span class="hljs-comment">// The Image ?</span>
            <span class="hljs-keyword">self</span>.<span class="hljs-type">ImageView</span>.image = <span class="hljs-type">UIImage</span>(named: playlist.image)
            <span class="hljs-comment">// the playlist title ?</span>
            <span class="hljs-keyword">self</span>.<span class="hljs-type">TitleLabel</span>.text = <span class="hljs-keyword">self</span>.playlist?.title

           }
       }
</code></pre>
<p>I think everything should work fine now, just as below ?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/demo3.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p> One last update to the UI: we have to add some padding and margins to the <code>section</code>  and <code>playlist</code> titles and make the playlist a little bit smaller.</p>
<p>Let's first add some padding for the section titles. To do that, we need just to give the <code>constant</code> property some number value inside the section cell <code>CustomCell</code> and within <code>setupSubCells</code>: </p>
<pre><code class="lang-swift"> collectionView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor,constant: <span class="hljs-number">15</span>).isActive = <span class="hljs-literal">true</span>
</code></pre>
<p>And if you see the entire <code>collectionView</code> come in at the bottom of the <code>titleLabel</code>, all we need to do is add more space by adding <code>15</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/paddingForTitles-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next we come to the title of the <code>playlist</code>. This will be inside <code>SubCustomCell</code>, and we just need to add more space at the bottom of the ImageView.</p>
<pre><code class="lang-swift"> <span class="hljs-type">ImageView</span>.bottomAnchor.constraint(equalTo: <span class="hljs-type">TitleLabel</span>.topAnchor,constant: -<span class="hljs-number">15</span>).isActive = <span class="hljs-literal">true</span>
</code></pre>
<p>We already have the constant there. In order for it to work, the value should be <code>-15</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/demo4.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Finally the playlist needs to be a little bit smaller. This is easy: we just make the <code>playlist</code> cell's height and width equal to the <code>section</code> cell's height divided by 2, just like below:</p>
<p><code>CustomCell.swift</code></p>
<pre><code class="lang-swift"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">CGSize</span> {

        <span class="hljs-keyword">let</span> width = frame.height / <span class="hljs-number">2</span>
        <span class="hljs-keyword">let</span> height = frame.height / <span class="hljs-number">2</span>

        <span class="hljs-keyword">return</span> <span class="hljs-type">CGSize</span>(width: width, height: height)

    }
</code></pre>
<p>Make the ImageView's height equal to <code>150</code> as well.</p>
<pre><code class="lang-swift">  <span class="hljs-comment">//SubCutomCell.swift</span>
  <span class="hljs-type">ImageView</span>.heightAnchor.constraint(equalToConstant: <span class="hljs-number">150</span>).isActive = <span class="hljs-literal">true</span>
</code></pre>
<p>And here we go ?.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/Screen-Shot-2019-12-09-at-9.55.19-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Perfect! I think that's enough for today – I don't want to make this article too long. So we will have another part where we will add the <code>TabBar</code> and the description, as well as some icons for the playlist.</p>
<p><strong>View the</strong> <a target="_blank" href="https://github.com/hayanisaid/autoLayout-programmatically-in-swift"><strong>Full source code on GitHub</strong></a><strong>?.</strong></p>
<p>Thanks for your time. I hope I haven't missed anything. If I did please @mention me on <a target="_blank" href="https://twitter.com/SaidHYN">Twitter</a>, or if you have any questions or an addition to this post the doors are always open to anyone. Thanks??.</p>
<p><strong><a target="_blank" href="https://webege.us16.list-manage.com/subscribe?u=311846a57d1e1a666287ad128&amp;id=2b386b2ebb">Subscribe</a></strong> <em>to my email list to be notified when the third part of this tutorial is published.</em> </p>
<blockquote>
<p>By the way, I’ve recently worked with a strong group of software engineers for one of my mobile applications. The organization was great, and the product was delivered very quickly, much faster than other firms and freelancers I’ve worked with, and I think I can honestly recommend them for other projects out there. Shoot me an email if you want to get in touch — <a target="_blank" href="mailto:said@devsdata.com">said@devsdata.com</a>.</p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to make an API call in Swift ]]>
                </title>
                <description>
                    <![CDATA[ By Ai-Lyn Tang If you are looking to become an iOS developer, there are some fundamental skills worth knowing. First, it's important to be familiar with creating table views. Second, you should know how to populate those table views with data. Third,... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-your-first-api-call-in-swift/</link>
                <guid isPermaLink="false">66d45d5e230dff0166905799</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 29 Nov 2019 11:49:45 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9ef3740569d1a4ca4004.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ai-Lyn Tang</p>
<p>If you are looking to become an iOS developer, there are some fundamental skills worth knowing. First, it's important to be familiar with creating table views. Second, you should know how to populate those table views with data. Third, it's great if you can fetch data from an API and use this data in your table view.</p>
<p>The third point is what we'll cover in this article. Since the introduction of <code>Codable</code> in Swift 4, making API calls is much easier. Previously most people used pods like Alamofire and SwiftyJson (you can read about how to do that <a target="_blank" href="https://code.likeagirl.io/3-steps-to-make-your-first-api-call-836e43ed702c">here</a>). Now the Swift way is much nicer out of the box, so there's no reason to download a pod.</p>
<p>Let's go through some building blocks that are often used to make an API call. We'll cover these concepts first, as they are important parts to understanding how to make an API call.</p>
<ul>
<li>Completion handlers</li>
<li><code>URLSession</code></li>
<li><code>DispatchQueue</code></li>
<li>Retain cycles</li>
</ul>
<p>Finally we'll put it all together. I'll be using the open source <a target="_blank" href="https://www.swapi.co/">Star Wars API</a> to build this project. You can see my full project code on <a target="_blank" href="https://github.com/ailyntang/starwars/">GitHub</a>.</p>
<p><em>Disclaimer alert: I am new to coding and am largely self-taught. Apologies if I misrepresent some concepts.</em></p>
<h2 id="heading-completion-handlers">Completion handlers</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/pheobe.jpeg" alt="Image" width="600" height="400" loading="lazy">
<em>Poor patient Pheobe</em></p>
<p>Remember the episode of Friends where Pheobe is glued to the phone for days waiting to speak with customer service? Imagine if at the very start of that phone call, a lovely person called Pip said: "Thanks for calling. I have no idea how long you'll need to wait on hold, but I'll call you back when we're ready for you." It wouldn't have been as funny, but Pip is offering to be a completion handler for Pheobe.</p>
<p>You use a completion handler in a function when you know that function will take a while to complete. You don't know how long, and you don't want to pause your life waiting for it to finish. So you ask Pip to tap you on the shoulder when she's ready to give you the answer. That way you can go about your life, run some errands, read a book, and watch TV. When Pip taps on you on the shoulder with the answer, you can take her answer and use it.</p>
<p>This is what happens with API calls. You send a URL request to a server, asking it for some data. You hope the server returns the data quickly, but you don't know how long it will take. Instead of making your user wait patiently for the server to give you the data, you use a completion handler. This means you can tell your app to go off and do other things, such as loading the rest of the page.</p>
<p>You tell the completion handler to tap your app on the shoulder once it has the information you want. You can specify what that information is. That way, when your app gets tapped on the shoulder, it can take the information from the completion handler and do something with it. Usually what you'll do is reload the table view so the data appears to the user.</p>
<p>Here's an example of what a completion handler looks like. The first example is setting up the API call itself:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">fetchFilms</span><span class="hljs-params">(completionHandler: @escaping <span class="hljs-params">([Film])</span></span></span> -&gt; <span class="hljs-type">Void</span>) {
  <span class="hljs-comment">// Setup the variable lotsOfFilms</span>
  <span class="hljs-keyword">var</span> lotsOfFilms: [<span class="hljs-type">Film</span>]

  <span class="hljs-comment">// Call the API with some code</span>

  <span class="hljs-comment">// Using data from the API, assign a value to lotsOfFilms  </span>

  <span class="hljs-comment">// Give the completion handler the variable, lotsOfFilms</span>
  completionHandler(lotsOfFilms)
}
</code></pre>
<p>Now we want to call the function <code>fetchFilms</code>. Some things to note:</p>
<ul>
<li>You don't need to reference <code>completionHandler</code> when you call the function. The only time you reference <code>completionHandler</code> is inside the function declaration.</li>
<li>The completion handler will give us back some data to use. Based on the function we've written above, we know to expect data which is of type <code>[Film]</code>. We need to name the data so that we can refer to it. Below I'm using the name <code>films</code>, but it could be <code>randomData</code>, or any other variable name I'd like.</li>
</ul>
<p>The code will look something like this: </p>
<pre><code class="lang-swift">fetchFilms() { (films) <span class="hljs-keyword">in</span>
  <span class="hljs-comment">// Do something with the data the completion handler returns </span>
  <span class="hljs-built_in">print</span>(films)
}
</code></pre>
<h2 id="heading-urlsession">URLSession</h2>
<p><code>URLSession</code> is like the manager of a team. The manager doesn't do anything on her own. Her job is to share the work with the people in her team, and they'll get the job done. Her team are <code>dataTasks</code>. Every time you need some data, write to the boss and use <code>URLSession.shared.dataTask</code>.  </p>
<p>You can give the <code>dataTask</code> different types of information to help you achieve your goal. Giving information to <code>dataTask</code> is called initialization. I initialism my <code>dataTasks</code> with URLs. <code>dataTasks</code> also use completion handlers as part of their initialization. Here's an example:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> url = <span class="hljs-type">URL</span>(string: <span class="hljs-string">"https://www.swapi.co/api/films"</span>)

<span class="hljs-keyword">let</span> task = <span class="hljs-type">URLSession</span>.shared.dataTask(with: url, completionHandler: { (data, response, error) <span class="hljs-keyword">in</span> 
  <span class="hljs-comment">// your code here</span>
})

task.resume()
</code></pre>
<p><code>dataTasks</code> use completion handlers, and they always return the same types of information: <code>data</code>, <code>response</code> and <code>error</code>. You can give these data types different names, like <code>(data, res, err)</code> or <code>(someData, someResponse, someError)</code>. For the sake of convention, it's best to stick to something obvious rather than go rogue with new variable names.</p>
<p>Let's start with <code>error</code>. If the <code>dataTask</code> returns an <code>error</code>, you'll  want to know that upfront. It means you can direct your code to handle the error gracefully. It also means you won't bother trying to read the data and do something with it as there is an error in returning the data. </p>
<p>Below I am handling the error really simply by printing an error to the console and exiting the function. There are many other ways you could handle the error if you wanted to. Think about how fundamental this data is to your app. For example, if you have a banking app and this API call shows users their balance, then you may want to handle the error by presenting a modal to the user that says, "Sorry, we're experiencing a problem right now. Please try again later."</p>
<pre><code class="lang-swift"><span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> error = error {
  <span class="hljs-built_in">print</span>(<span class="hljs-string">"Error accessing swapi.co: /(error)"</span>)
  <span class="hljs-keyword">return</span>
}
</code></pre>
<p>Next we look at the response. You can cast the response to be an <code>httpResponse</code>. That way you can look at the status codes and make some decisions based on the code. For example, if the status code is 404, then you know the page was not found. </p>
<p>The code below uses a <code>guard</code> to check that two things exist. If both exist, then it allows the code to continue to the next statement after the <code>guard</code> clause. If either of the statements fail, then we exit the function. This is a typical use case of a <code>guard</code> clause. You expect the code after a guard clause to be the happy days flow (i.e. the easy flow with no errors).</p>
<pre><code class="lang-swift">  <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> httpResponse = response <span class="hljs-keyword">as</span>? <span class="hljs-type">HTTPURLResponse</span>,
            (<span class="hljs-number">200</span>...<span class="hljs-number">299</span>).<span class="hljs-built_in">contains</span>(httpResponse.statusCode) <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Error with the response, unexpected status code: \(response)"</span>)
    <span class="hljs-keyword">return</span>
  }
</code></pre>
<p>Finally you handle the data itself. Notice that we haven't used the completion handler for the <code>error</code> or the <code>response</code>. That's because the completion handler is waiting for data from the API. If it doesn't get to the data part of the code, there's no need to invoke the handler.</p>
<p>For the data, we are using the <code>JSONDecoder</code> to parse the data in a nice way. This is pretty nifty, but requires that you have established a model. Our model is called <code>FilmSummary</code>. If <code>JSONDecoder</code> is new to you, then have a look online for how to use it and how to use <code>Codable</code>. It's really simple in Swift 4 and above compared to the Swift 3 days.</p>
<p>In the code below, we are first checking that the data exists. We are pretty sure it should exist, because there are no errors and no strange HTTP responses. Second, we check that we can parse the data we receive in the way we expect. If we can, then we return the film summary to the completion handler. Just in case there is no data to return from the API, we have a fall back plan of the empty array.</p>
<pre><code class="lang-swift"><span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> data = data,
        <span class="hljs-keyword">let</span> filmSummary = <span class="hljs-keyword">try</span>? <span class="hljs-type">JSONDecoder</span>().decode(<span class="hljs-type">FilmSummary</span>.<span class="hljs-keyword">self</span>, from: data) {
        completionHandler(filmSummary.results ?? [])
      }
</code></pre>
<p>So the full code for API call looks like this:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">fetchFilms</span><span class="hljs-params">(completionHandler: @escaping <span class="hljs-params">([Film])</span></span></span> -&gt; <span class="hljs-type">Void</span>) {
    <span class="hljs-keyword">let</span> url = <span class="hljs-type">URL</span>(string: domainUrlString + <span class="hljs-string">"films/"</span>)!

    <span class="hljs-keyword">let</span> task = <span class="hljs-type">URLSession</span>.shared.dataTask(with: url, completionHandler: { (data, response, error) <span class="hljs-keyword">in</span>
      <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> error = error {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"Error with fetching films: \(error)"</span>)
        <span class="hljs-keyword">return</span>
      }

      <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> httpResponse = response <span class="hljs-keyword">as</span>? <span class="hljs-type">HTTPURLResponse</span>,
            (<span class="hljs-number">200</span>...<span class="hljs-number">299</span>).<span class="hljs-built_in">contains</span>(httpResponse.statusCode) <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"Error with the response, unexpected status code: \(response)"</span>)
        <span class="hljs-keyword">return</span>
      }

      <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> data = data,
        <span class="hljs-keyword">let</span> filmSummary = <span class="hljs-keyword">try</span>? <span class="hljs-type">JSONDecoder</span>().decode(<span class="hljs-type">FilmSummary</span>.<span class="hljs-keyword">self</span>, from: data) {
        completionHandler(filmSummary.results ?? [])
      }
    })
    task.resume()
  }
</code></pre>
<h2 id="heading-retain-cycles">Retain cycles</h2>
<p><em>NB: I am extremely new to understanding retain cycles! Here's the gist of what I researched online.</em></p>
<p>Retain cycles are important to understand for memory management. Basically you want your app to clean up bits of memory that it doesn't need anymore. I assume this makes the app more performant. </p>
<p>There are lots of ways that Swift helps you do this automatically. However there are many ways that you can accidentally code retain cycles into your app. A retain cycle means that your app will always hold on to the memory for a certain piece of code. Generally it happens when you have two things that have strong pointers to each other. </p>
<p>To get around this, people often use <code>weak</code>. When one side of the code is <code>weak</code>, you don't have a retain cycle and your app will be able to release the memory. </p>
<p>For our purpose, a common pattern is to use <code>[weak self]</code> when calling the API. This ensures that once the completion handler returns some code, the app can release the memory.</p>
<pre><code class="lang-swift">fetchFilms { [<span class="hljs-keyword">weak</span> <span class="hljs-keyword">self</span>] (films) <span class="hljs-keyword">in</span>
  <span class="hljs-comment">// code in here</span>
}
</code></pre>
<h2 id="heading-dispatchqueue">DispatchQueue</h2>
<p>Xcode uses different threads to execute code in parallel. The advantage of multiple threads means you aren't stuck waiting on one thing to finish before you can move on to the next. Hopefully you can start to see the links to completion handlers here.</p>
<p>These threads seem to be also called dispatch queues. API calls are handled on one queue, typically a queue in the background. Once you have the data from your API call, most likely you'll want to show that data to the user. That means you'll want to refresh your table view.</p>
<p>Table views are part of the UI, and all UI manipulations should be done in the main dispatch queue. This means somewhere in your view controller file, usually as part of the <code>viewDidLoad</code> function, you should have a bit of code that tells your table view to refresh. </p>
<p>We only want the table view to refresh once it has some new data from the API. This means we'll use a completion handler to tap us on the shoulder and tell us when that API call is finished. We'll wait until that tap before we refresh the table.</p>
<p>The code will look something like:</p>
<pre><code class="lang-swift">fetchFilms { [<span class="hljs-keyword">weak</span> <span class="hljs-keyword">self</span>] (films) <span class="hljs-keyword">in</span>
  <span class="hljs-keyword">self</span>.films = films

  <span class="hljs-comment">// Reload the table view using the main dispatch queue</span>
  <span class="hljs-type">DispatchQueue</span>.main.async {
    tableView.reloadData()
  }
}
</code></pre>
<h2 id="heading-viewdidload-vs-viewdidappear">viewDidLoad vs viewDidAppear</h2>
<p>Finally you need to decide where to call your <code>fetchfilms</code> function. It will be inside a view controller that will use the data from the API. There are two obvious places you could make this API call. One is inside <code>viewDidLoad</code> and the other is inside <code>viewDidAppear</code>.</p>
<p>These are two different states for your app. My understanding is <code>viewDidLoad</code> is called the first time you load up that view in the foreground. <code>viewDidAppear</code> is called every time you come back to that view, for example when you press the back button to come back to the view.</p>
<p>If you expect your data to change in between the times that the user will navigate to and from that view, then you may want to put your API call in <code>viewDidAppear</code>. However I think for almost all apps, <code>viewDidLoad</code> is sufficient. Apple recommends <code>viewDidAppear</code> for all API calls, but that seems like overkill. I imagine it would make your app less performant as it's making many more API calls that it needs to.</p>
<h2 id="heading-combining-all-the-steps">Combining all the steps</h2>
<p>First: write the function that calls the API. Above, this is <code>fetchFilms</code>. This will have a completion handler, which will return the data you are interested in. In my example, the completion handler returns an array of films.</p>
<p>Second: call this function in your view controller. You do this here because you want to update the view based on the data from the API. In my example, I am refreshing a table view once the API returns the data.</p>
<p>Third: decide where in your view controller you would like to call the function. In my example, I call it in <code>viewDidLoad</code>.</p>
<p>Fourth: decide what to do with the data from the API. In my example, I am refreshing a table view.</p>
<p>Inside <code>NetworkManager.swift</code> (this function can be defined in your view controller if you'd like, but I am using the MVVM pattern).</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">fetchFilms</span><span class="hljs-params">(completionHandler: @escaping <span class="hljs-params">([Film])</span></span></span> -&gt; <span class="hljs-type">Void</span>) {
    <span class="hljs-keyword">let</span> url = <span class="hljs-type">URL</span>(string: domainUrlString + <span class="hljs-string">"films/"</span>)!

    <span class="hljs-keyword">let</span> task = <span class="hljs-type">URLSession</span>.shared.dataTask(with: url, completionHandler: { (data, response, error) <span class="hljs-keyword">in</span>
      <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> error = error {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"Error with fetching films: \(error)"</span>)
        <span class="hljs-keyword">return</span>
      }

      <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> httpResponse = response <span class="hljs-keyword">as</span>? <span class="hljs-type">HTTPURLResponse</span>,
            (<span class="hljs-number">200</span>...<span class="hljs-number">299</span>).<span class="hljs-built_in">contains</span>(httpResponse.statusCode) <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">print</span>(<span class="hljs-string">"Error with the response, unexpected status code: \(response)"</span>)
        <span class="hljs-keyword">return</span>
      }

      <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> data = data,
        <span class="hljs-keyword">let</span> filmSummary = <span class="hljs-keyword">try</span>? <span class="hljs-type">JSONDecoder</span>().decode(<span class="hljs-type">FilmSummary</span>.<span class="hljs-keyword">self</span>, from: data) {
        completionHandler(filmSummary.results ?? [])
      }
    })
    task.resume()
  }
</code></pre>
<p>Inside <code>FilmsViewController.swift</code>:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FilmsViewController</span>: <span class="hljs-title">UIViewController</span> </span>{
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> films: [<span class="hljs-type">Film</span>]?

  <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">viewDidLoad</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">super</span>.viewDidLoad()

    <span class="hljs-type">NetworkManager</span>().fetchFilms { [<span class="hljs-keyword">weak</span> <span class="hljs-keyword">self</span>] (films) <span class="hljs-keyword">in</span>
      <span class="hljs-keyword">self</span>?.films = films
      <span class="hljs-type">DispatchQueue</span>.main.async {
        <span class="hljs-keyword">self</span>?.tableView.reloadData()
      }
    }
  }

  <span class="hljs-comment">// other code for the view controller</span>
}
</code></pre>
<p>Gosh, we made it! Thanks for sticking with me.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to programmatically build a Spotify clone for iOS with AutoLayout ]]>
                </title>
                <description>
                    <![CDATA[ By Said Hayani In this post we will try to re-create the Spotify home screen layout in Swift programmatically. Why programmatically? I think it's always good to know how to build things in different ways, and I like to write code to do things program... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/autolayout-programmatically-spotify-clone-in-swift/</link>
                <guid isPermaLink="false">66d460c9d14641365a050963</guid>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ios app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Xcode ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 03 Nov 2019 01:04:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/featured_image-2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Said Hayani</p>
<p>In this post we will try to re-create the Spotify home screen layout in Swift programmatically. Why programmatically? I think it's always good to know how to build things in different ways, and I like to write code to do things programmatically. These skills are especially helpful if you are working with team or using version control. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/spotify-demo.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is the actual home screen of Spotify's mobile app. So to achieve this kind of layout, we will be using <code>UICollectionView</code>, and we may use <code>TabBarController</code> as well to create the tab navigator.</p>
<blockquote>
<p>Basic requirement : First  make sure you have Xcode +10 installed and swift +4.</p>
</blockquote>
<p>Let's start by creating a new Xcode project using Xcode:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-10-31-at-8.03.13-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And the first thing we need to do in <code>ViewController.swift</code> is change the superClass to <code>UICollectionViewController</code> instead of  <code>UIViewController</code> because our class will be based on <code>collectionView</code>.</p>
<pre><code class="lang-swift"><span class="hljs-comment">//</span>
<span class="hljs-comment">//  ViewController.swift</span>
<span class="hljs-comment">//  spotifyAutoLayout</span>
<span class="hljs-comment">//</span>
<span class="hljs-comment">//  Created by admin on 10/31/19.</span>
<span class="hljs-comment">//  Copyright © 2019 Said Hayani. All rights reserved.</span>
<span class="hljs-comment">//</span>

<span class="hljs-keyword">import</span> UIKit

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ViewController</span>: <span class="hljs-title">UICollectionViewController</span> </span>{

    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">viewDidLoad</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">super</span>.viewDidLoad()
        collectionView.backgroundColor = .purple
        <span class="hljs-comment">// Do any additional setup after loading the view.</span>
    }


}
</code></pre>
<p>If you try to run the app the build will fail. We need to add some code to the <code>AppDelegate.swift</code> file within the <code>didFinishLaunchingWithOptions</code> function past this piece of code before the  <code>return</code> statement:</p>
<pre><code class="lang-swift">  <span class="hljs-keyword">let</span> layout = <span class="hljs-type">UICollectionViewFlowLayout</span>()
        window = <span class="hljs-type">UIWindow</span>()
        window?.rootViewController = <span class="hljs-type">ViewController</span>(collectionViewLayout: layout)
</code></pre>
<p>And the code should look like this:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">application</span><span class="hljs-params">(<span class="hljs-number">_</span> application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: <span class="hljs-keyword">Any</span>]?)</span></span> -&gt; <span class="hljs-type">Bool</span> {
        <span class="hljs-comment">// Override point for customization after application launch.</span>
        <span class="hljs-keyword">let</span> layout = <span class="hljs-type">UICollectionViewFlowLayout</span>()
        window = <span class="hljs-type">UIWindow</span>()
        window?.rootViewController = <span class="hljs-type">ViewController</span>(collectionViewLayout: layout)
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
    }
</code></pre>
<p>Now you should be able to run the app and see the <code>backgroundColor</code> changed to <code>purple</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/first-look.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The next step is to distribute the layout and divide the space equally between the sections.</p>
<p>Let's define the methods of our <code>CollectionView</code>.</p>
<p>The steps:</p>
<ul>
<li>Register a reusable cell with unique identifier</li>
<li>Define the number of the items in the section</li>
<li>Use the the registered cell   </li>
</ul>
<p>To use some of <code>CollectionView</code> methods we need to always conform to <code>UICollectionViewDelegateFlowLayout</code> as a superClass and to get the autoComplete of the methods. So let's start with registering the CollectionViewCell.</p>
<p>Inside <code>View.DidLoad()</code> we call the <code>collectionView.register()</code> method to register the reusable cell:</p>
<pre><code class="lang-swift">  collectionView.register(<span class="hljs-type">UICollectionViewCell</span>.<span class="hljs-keyword">self</span>, forCellWithReuseIdentifier: cellId)
</code></pre>
<p>Then we define the number of cells we will have inside the <code>collectionView</code> using <code>numberOfItemsInSection</code>.  For now we just need to make it 5 items:</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, numberOfItemsInSection section: Int)</span></span> -&gt; <span class="hljs-type">Int</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-number">5</span>
    }
</code></pre>
<p>The next step is to define the reusable cell using <code>cellForItemAt</code> that should return <code>UICollectionViewCell</code> and have a unique id called <code>cellId</code>. The code looks like this:</p>
<pre><code class="lang-swift"> <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">UICollectionViewCell</span> {
        <span class="hljs-keyword">let</span> cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, <span class="hljs-keyword">for</span>: indexPath)
        cell.backgroundColor = .red
        <span class="hljs-keyword">return</span> cell
    }
</code></pre>
<p>The full code should look like this:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> UIKit

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ViewController</span>: <span class="hljs-title">UICollectionViewController</span>, <span class="hljs-title">UICollectionViewDelegateFlowLayout</span> </span>{
    <span class="hljs-keyword">let</span> cellId : <span class="hljs-type">String</span> = <span class="hljs-string">"cellId"</span>

    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">viewDidLoad</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">super</span>.viewDidLoad()
        collectionView.backgroundColor = .purple
        collectionView.register(<span class="hljs-type">UICollectionViewCell</span>.<span class="hljs-keyword">self</span>, forCellWithReuseIdentifier: cellId)

    }


    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, numberOfItemsInSection section: Int)</span></span> -&gt; <span class="hljs-type">Int</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-number">5</span>
    }
    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">UICollectionViewCell</span> {
        <span class="hljs-keyword">let</span> cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, <span class="hljs-keyword">for</span>: indexPath)
        cell.backgroundColor = .red
        <span class="hljs-keyword">return</span> cell
    }

}
</code></pre>
<p>You should be able to see 5 items with red backgrounds on the screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/cellItem.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-add-a-custom-width-and-height-to-the-cells">Add a custom width and height to the cells</h2>
<p>Now we need to place the cells in the correct order and give them a <code>width</code> and <code>height</code>. Each cell will take the <code>width</code> of the screen as <code>width</code>.</p>
<p>We are lucky to have <code>sizeForItemAt</code> method so we can give the cells a custom <code>width</code> and <code>height</code>. It's a method that should return a <code>CGSize</code> type:</p>
<pre><code class="lang-swift"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">CGSize</span> {
        <span class="hljs-keyword">let</span> width = view.frame.width
        <span class="hljs-keyword">let</span> height = <span class="hljs-type">CGFloat</span>(<span class="hljs-number">200</span>)

        <span class="hljs-keyword">return</span> <span class="hljs-type">CGSize</span>(width: width, height: height)
    }
</code></pre>
<p>So we made the  <code>Cell</code> take the <code>width</code> of the screen by using <code>view.frame.width</code> and a custom <code>height</code> with is a <code>CGFloat</code> type.</p>
<p>Now you can see the result below in your Simulator :</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-10-31-at-9.05.46-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Everything looks good so far. This time let's create a custom cell that can be reusable. Create a new Swift file named <code>CustomCell</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-10-31-at-11.52.10-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><code>CustomCell.swift</code> should look like this below:</p>
<pre><code class="lang-swift">
<span class="hljs-keyword">import</span> UIKit

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CustomCell</span>: <span class="hljs-title">UICollectionViewCell</span> </span>{
    <span class="hljs-keyword">override</span> <span class="hljs-keyword">init</span>(frame: <span class="hljs-type">CGRect</span>) {
        <span class="hljs-keyword">super</span>.<span class="hljs-keyword">init</span>(frame: frame)

    }

    <span class="hljs-keyword">required</span> <span class="hljs-keyword">init</span>?(coder aDecoder: <span class="hljs-type">NSCoder</span>) {
        <span class="hljs-built_in">fatalError</span>(<span class="hljs-string">"init(coder:) has not been implemented"</span>)
    }
}
</code></pre>
<p>Now the next things we have to do is to modify two methods to support the reusable cell, <code>collectionView.register</code> and <code>cellForItemAt</code>.  Let's first modify the register method. Replace <code>UICollectionViewCell.**self**</code> with <code>CustomCell</code>:</p>
<pre><code class="lang-swift"> collectionView.register(<span class="hljs-type">UICollectionViewCell</span>.<span class="hljs-keyword">self</span>, forCellWithReuseIdentifier: cellId)
</code></pre>
<p>Next we need to cast <code>cellForItemAt</code> to conform to <code>CustomCell</code> like below:</p>
<pre><code class="lang-swift">  <span class="hljs-keyword">let</span> cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, <span class="hljs-keyword">for</span>: indexPath) <span class="hljs-keyword">as</span>! <span class="hljs-type">CustomCell</span>
</code></pre>
<p>If you run the app probably you won't notice any change, so give the CustomCell a backgroundColor <code>backgroundColor = .yellow</code>. Don't forget to remove the line <code>cell.backgroundColor = .red</code> in <code>cellForItemAt</code>. You should see the background color changed to yellow ?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-01-at-12.13.20-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now it's time to put some salt into <code>CutomCell</code> :D</p>
<p>If you look at the Spotify home screen, each section which is a <code>CustomCell</code> in our example contains a section title, sub cells, and is horizontal:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/spotify-demo-1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-add-a-section-title">Add a section title</h2>
<p>Let's add a title label to the cell. Create the <code>titleLabel</code> element inside the <code>CutomCell</code> class:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> titleLabel: <span class="hljs-type">UILabel</span> = {
        <span class="hljs-keyword">let</span> lb  = <span class="hljs-type">UILabel</span>()
        lb.text = <span class="hljs-string">"Section Title"</span>
        lb.font = <span class="hljs-type">UIFont</span>.boldSystemFont(ofSize: <span class="hljs-number">14</span>)
        lb.font = <span class="hljs-type">UIFont</span>.boldSystemFont(ofSize: <span class="hljs-number">14</span>)

        <span class="hljs-keyword">return</span> lb
    }()
</code></pre>
<p>Then add the element to the view inside <code>init()</code> block:</p>
<pre><code class="lang-swift">addSubview(titleLabel)
</code></pre>
<p>If you run the app you won't see any changes, and that's because we didn't put any constraint to the element yet. So let's add some constraints – add this property              <code>lb.translatesAutoresizingMaskIntoConstraints = **false**</code> to <code>titleLabel</code> to be able to apply constraints to the element:</p>
<p>After we add <code>titleLabel</code> to the view, we define the constraints:</p>
<pre><code class="lang-swift"> addSubview(titleLabel)
titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: <span class="hljs-number">8</span>).isActive = truetitleLabel.leftAnchor.constraint(equalTo: leftAnchor,constant: <span class="hljs-number">8</span> ).isActive = <span class="hljs-literal">true</span>
</code></pre>
<p>Always make sure to add <code>.isActive = true</code> property – without it the constraint won't work!        </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-01-at-12.32.55-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Before we move on to the next part, let's first change the background color of the screen to black and also remove the yellow color for the cells:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-01-at-12.46.01-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now comes the big part: putting sub cells into each cell. To achieve that we are going to add a <code>CollectionView</code> inside <code>CustomCell</code>.</p>
<p>To add a <code>CollectionView</code> inside <code>UICollectionViewCell</code> we need to add  properties <code>UICollectionViewDelegate</code>, <code>UICollectionViewDelegateFlowLayout</code>, and <code>UICollectionViewDataSource</code> as superClass to <code>CustomCell</code>.</p>
<p>Let's create the <code>collectionView</code> element as any simple view:</p>
<pre><code class="lang-swift">
    <span class="hljs-keyword">let</span> collectionView : <span class="hljs-type">UICollectionView</span> = {
        <span class="hljs-comment">// init the layout</span>
        <span class="hljs-keyword">let</span> layout = <span class="hljs-type">UICollectionViewFlowLayout</span>()
        <span class="hljs-comment">// set the direction to be horizontal</span>
        layout.scrollDirection = .horizontal

        <span class="hljs-comment">// the instance of collectionView</span>

        <span class="hljs-keyword">let</span> cv = <span class="hljs-type">UICollectionView</span>(frame: .zero, collectionViewLayout: layout)

        <span class="hljs-comment">// Activate constaints</span>

        cv.translatesAutoresizingMaskIntoConstraints = <span class="hljs-literal">false</span>

        <span class="hljs-keyword">return</span> cv

    }()
</code></pre>
<p>Notice that we add <code>layout</code> to the <code>collectionView</code> as layer in the initializer as we did the first time with the <code>viewController.swift</code>. Here we also specify the direction of the <code>FlowLayout</code> to be <code>.horizontal</code>.</p>
<p>Let's add the <code>collectionView</code> element to the view as subView.</p>
<p> We gonna make a function that do that for us to make the code a little bit cleaner.</p>
<pre><code class="lang-swift">    <span class="hljs-keyword">fileprivate</span>  <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">setupSubCells</span><span class="hljs-params">()</span></span>{
        <span class="hljs-comment">// add collectionView to the view</span>
        addSubview(collectionView)

        collectionView.dataSource = <span class="hljs-keyword">self</span>
        collectionView.delegate = <span class="hljs-keyword">self</span>
        <span class="hljs-comment">// setup constrainst</span>
        <span class="hljs-comment">// make it fit all the space of the CustomCell</span>
        collectionView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor).isActive = <span class="hljs-literal">true</span>
        collectionView.leftAnchor.constraint(equalTo: leftAnchor).isActive = <span class="hljs-literal">true</span>
        collectionView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = <span class="hljs-literal">true</span>
        collectionView.rightAnchor.constraint(equalTo: rightAnchor).isActive = <span class="hljs-literal">true</span>
    }
</code></pre>
<p>Make sure to set delegate to <code>self</code> for the <code>collectionView</code> and the dataSource as well:</p>
<p>  <code>collectionView.dataSource = self</code></p>
<p>   <code>collectionView.delegate = self</code> </p>
<p>Then call the function within <code>init</code> block.</p>
<p>Xcode will display some errors if you trying to build the app because we are not conforming to <code>UICollectionViewDelegate</code> and <code>UICollectionViewDelegateFlowLayout</code> protocols. To fix that we need first to register the sub cell as a reusable cell.</p>
<p>Create a variable at the top of the class and give it a name of <code>cellId</code> so we can use it when we need the cell identifier: </p>
<p><code>let cellId : String = "subCellID"</code></p>
<pre><code class="lang-swift">collectionView.register(<span class="hljs-type">UICollectionViewCell</span>.<span class="hljs-keyword">self</span>, forCellWithReuseIdentifier: cellId)
</code></pre>
<p>Now we're missing two more methods to make the errors go away: <code>numberOfItemsInSection</code> that define the number of cells in the section and <code>cellForItemAt</code> that define the reusable cell. These methods are necessary for  <code>collectionView</code> to work properly:</p>
<pre><code class="lang-swift"> <span class="hljs-comment">// number of cells</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, numberOfItemsInSection section: Int)</span></span> -&gt; <span class="hljs-type">Int</span> {
       <span class="hljs-keyword">return</span>  <span class="hljs-number">4</span>
    }

    <span class="hljs-comment">// reusable Cell</span>
     <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">UICollectionViewCell</span> {
        <span class="hljs-keyword">let</span> cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, <span class="hljs-keyword">for</span>: indexPath)
         cell.backgroundColor = .yellow

        <span class="hljs-keyword">return</span> cell
    }
</code></pre>
<p>The results should look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-01-at-1.40.42-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As you can see, the <code>collectionView</code> are in purple as background and sub cells are yellow.</p>
<p>The last things we can do before ending this article is make <code>subCells</code> have the height of the section and as width. Again we are using <code>sizeForItemAt</code> to define the <code>height</code> and the <code>width</code> of the cell .</p>
<pre><code class="lang-swift"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">CGSize</span> {

        <span class="hljs-keyword">let</span> width = frame.height
        <span class="hljs-keyword">let</span> height = frame.height

        <span class="hljs-keyword">return</span> <span class="hljs-type">CGSize</span>(width: width, height: height)

    }
</code></pre>
<p>And here we are ?:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/complet-layout-demo1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>NICE! I'm gonna stop at this point so this post isn't too long. I'll make a second part where we are going to add some mocked pictures and fill it with some data.</p>
<h3 id="heading-full-source-code-herehttpsgithubcomhayanisaidautolayout-programmatically-in-swift">Full source code ? <a target="_blank" href="https://github.com/hayanisaid/autoLayout-programmatically-in-swift">here</a></h3>
<p>Please please if you have any additions, questions, or corrections, post it in the comments below ? or hit me up on <a target="_blank" href="https://twitter.com/SaidHYN">Twitter</a>.</p>
<p><strong><a target="_blank" href="https://webege.us16.list-manage.com/subscribe?u=311846a57d1e1a666287ad128&amp;id=2b386b2ebb">Subscribe</a></strong> to my email list to be notified when the second part of this tutorial is published </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to build design system with SwiftUI ]]>
                </title>
                <description>
                    <![CDATA[ By Vince MingPu Shao Building a design system to support one product is not easy - it has to be robust and flexible at the same time for scalability. Though challenging, lots of great resources have shared useful principles and approaches that help t... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-design-system-with-swiftui/</link>
                <guid isPermaLink="false">66d4617736c45a88f96b7d13</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design Systems ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SwiftUI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 09 Sep 2019 23:42:20 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/09/preview-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Vince MingPu Shao</p>
<p>Building a design system to support one product is not easy - it has to be robust and flexible at the same time for scalability. Though challenging, <a target="_blank" href="https://www.designbetter.co/design-systems-handbook/building-design-system">lots</a> <a target="_blank" href="https://lightningdesignsystem.com/design-tokens/">of</a> <a target="_blank" href="https://medium.com/eightshapes-llc/tokens-in-design-systems-25dd82d58421">great</a> <a target="_blank" href="https://www.youtube.com/watch?v=wDBEc3dJJV8">resources</a> have shared useful principles and approaches that help teams build a good system both visually and programmatically. Standing on their shoulders, this article tries to contribute to an untouched ground by focusing on building a good system in <code>SwiftUI</code>.</p>
<h2 id="heading-why-do-i-write-this-article">Why do I write this article</h2>
<p>During my first summer in <a target="_blank" href="https://tisch.nyu.edu/itp">ITP</a> at New York, I'm lucky to have the opportunity to work as an iOS developer intern at <a target="_blank" href="https://www.linebreak.studio/">Line Break Studio</a>. One task I've been assigned to is building a design system in two steps: first visually in <a target="_blank" href="https://www.sketch.com/">Sketch</a>, and then programmatically in <code>SwiftUI</code>. The experience of experimenting with the new framework and building a design system with it has been amazing, but also buggy along the way. That's why we'd like to share our experience with the community, hopefully making your development process easier.</p>
<hr>
<h2 id="heading-what-is-swiftuihttpsdeveloperapplecomdocumentationswiftui">What is <a target="_blank" href="https://developer.apple.com/documentation/swiftui">SwiftUI</a></h2>
<p>Apple released this groundbreaking new framework in <a target="_blank" href="https://developer.apple.com/videos/wwdc2019/?q=swiftui">WWDC 2019</a>, which is one of the bests in years. From the point of view as a web developer, the project development experience in <code>SwiftUI</code> is closer to which in conventional front-end stack and frameworks.</p>
<p>This is definitely an awesome move because programming interface and managing states are drastically easier than before. And the best part of this improvement is that one can <a target="_blank" href="https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit">integrate UIKit and SwiftUI smoothly</a>. To learn the basics of SwiftUI, the <a target="_blank" href="https://developer.apple.com/tutorials/swiftui/tutorials">official tutorials</a> provided by Apple are very helpful.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/aH7oWxfxpJY" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-the-demo-project">The demo project</h2>
<p>For demonstration purpose, I put up a simplified version of design system we built in <a target="_blank" href="https://www.linebreak.studio/">Line Break Studio</a>. It a set of <strong>button</strong> components in different forms, which are built on top of two lower level parts: <strong>typography</strong> and <strong>colorPalette</strong>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/preview-record.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Dynamic rendering view of the demo project</em></p>
<p>The project is <a target="_blank" href="https://github.com/vince19972/SwiftUI-Design-System-Demo">public on GitHub</a>, and I'm using <code>Xcode 11 Beta 5</code> for development. An <a target="_blank" href="https://airtable.com/shrHQdv9vQGz7UMQj">Airtable base</a> as design system management hub (read <a target="_blank" href="https://www.vinceshao.com/blog/a-better-web-development-workflow-confluence-airtable-jira-and-abstract">more about workflow management</a>) is also public for reference.</p>
<hr>
<h2 id="heading-principles-of-building-design-system">Principles of building design system</h2>
<p>Design system in code is a middleware between designers and developers. Developer of the system takes inputs from design system in visual form, and produces API that's identical with which for further development. Following two principles should be recognized to complete this system in code:</p>
<h3 id="heading-1-communicate-with-tokenshttpsmediumcomeightshapes-llctokens-in-design-systems-25dd82d58421">1. Communicate with <a target="_blank" href="https://medium.com/eightshapes-llc/tokens-in-design-systems-25dd82d58421">tokens</a></h3>
<p>Fundamentally, the purpose of having a design system in program is not about better code management or development efficiency, but to make sure the <strong>view</strong> is consistent with design files. To achieve that goal, using tokens to signify certain color, font, size or any visual elements is crucial to maintain quality of communication between developers, designers and managers in a team.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/lightning-token.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://www.lightningdesignsystem.com/design-tokens/">Lightning Design System</a>'s tokens built by Salesforce</em></p>
<h3 id="heading-2-levels-of-hierarchy">2. Levels of hierarchy</h3>
<p>In <a target="_blank" href="https://medium.com/eightshapes-llc/tokens-in-design-systems-25dd82d58421">EightShapes' article</a>, it points out that we should "Show options first, then decisions next", because "You can't make decisions without options."</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/eightshape-article.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://medium.com/eightshapes-llc/tokens-in-design-systems-25dd82d58421">EightShapes' article</a> about design tokens</em></p>
<p>This kind of ordering architecture loosens  the degree of coupling between different levels, hence providing more flexibility and dynamic for possible revisions. The way I structure the levels is in this order from bottom to top: material → base → token. But it could be anyway the team's comfortable with.</p>
<hr>
<h2 id="heading-diving-into-code">Diving into code</h2>
<p>Following section is a list of highlights we'd like to point out based on our experience. Please <a target="_blank" href="https://github.com/vince19972/SwiftUI-Design-System-Demo">visit the GitHub repo</a> for complete code. Any feedbacks or critics are welcome for improvements.</p>
<h3 id="heading-1-architecting-levels-of-hierarchy">1. Architecting levels of hierarchy</h3>
<p>There're two ways of stacking materials at lower level to construct tokens at highest level:</p>
<ul>
<li><strong>Use <code>enum</code> for type safety and code literacy</strong></li>
</ul>
<p>Advantages of using enum in code as grouping wrapper or parameter in function have already been well recognized. One point worths mentioning here is the implementation of levels of hierarchy.</p>
<p>We always store the raw values, including font size (<code>CGFloat</code>) and font name (<code>String</code>), at the lowest level, because we don't want to mess around with it. But because raw value must be a literal in enum, we can't just assign a <code>case</code> to be a value from the other enum.</p>
<p>To work around this problem, we implement a function <code>getValue</code>, which returns the raw value in <code>switch</code> case when necessary.</p>




<ul>
<li><strong>Use <code>struct</code> for easier structure</strong></li>
</ul>
<p>Though enum is great, we don't need its unique feature in some cases. For example, because <code>Xcode</code> takes care of the heavy job of processing dynamic colors, and no parameter options are required in API endpoint, we can set up color palettes by simple two levels of struct.</p>




<h3 id="heading-2-clear-and-straightforward-naming-of-api-endpoint">2. Clear and straightforward naming of <code>API</code> endpoint</h3>
<p>Naming convention is another broad topic for discussion and debate. In addition to basic <a target="_blank" href="https://swift.org/documentation/api-design-guidelines/">Swift conventions</a>, the only two rules we abide are, 1) no acronym and 2) making it simple. For example, to use typography and color system, instead of creating new endpoints, we make extension from Font and Color structs. This approach decreases the effort to memorize unfamiliar API names for developers.</p>




<h3 id="heading-3-manage-color-sets-dynamically-in-two-modes">3. Manage color sets dynamically in two modes</h3>
<p>So dark mode has become a standard in industry, and both <a target="_blank" href="https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/dark-mode/">iOS</a> and <a target="_blank" href="https://material.io/design/color/dark-theme.html">Android</a> team have implemented this feature. It's a good trend for users, but could bring designers and developers some challenges, including managing and naming the color sets, especially gray scale ones.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/material-dark.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://material.io/design/color/dark-theme.html">Material Design</a>'s dark theme guide</em></p>
<p>To think and communicate about gray scale colors dynamically, using terms like <em>white</em>, <em>light</em>, <em>black</em> or <em>dark</em> doesn't work. Because if we referred to a dynamic color <code>#000000</code> (black in HEX) <em>black</em> or <em>dark</em> in <code>light color scheme</code>, how do you talk about this particular color, which should turn into <code>#FFFFFF</code> (white in HEX), in <code>dark color scheme</code>? <em>defaultDark</em> or <em>lightDark</em>?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/color-transition.png" alt="Image" width="600" height="400" loading="lazy">
<em>Confusing transition of color sets</em></p>
<p>It is very confusing to name gray scale dynamic color sets in conventional approach. To avoid this confusion, we use <code>theme</code> and <code>contrast</code> to manage one set of color in <code>light</code> and <code>dark</code> schemes instead.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/airtable-color-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Example color naming in demo <a target="_blank" href="https://airtable.com/shrHQdv9vQGz7UMQj">Airtable base</a></em></p>
<p>Note that a gray scale color doesn't always need to be reversed in opposite color mode. In these situations that light color remains light and dark remains dark, we simply name name it light or dark instead.</p>
<p>Once we wrap our head around this naming method, managing this architecture of color palette is easy in <code>Xcode</code>. To create a color set, simply create a new <code>Asset Catalog</code> file → add a new <code>Color Set</code> → and change <code>Appearances</code> to <code>Any, Light, Dark</code> will do.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/color-asset.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to add color asset in Xcode</em></p>
<h3 id="heading-4-environment-settings">4. <code>environment</code> settings</h3>
<p>One awesome feature in SwiftUI framework is the <a target="_blank" href="https://developer.apple.com/documentation/swiftui/environment">environment modifier</a>, which provides ability to control <a target="_blank" href="https://developer.apple.com/documentation/swiftui/environmentvalues">environment values</a> on target view. In terms of building design system, this ability provides convenient approach to change app's font at root level. And the other advantage of using <code>environmentValue</code> is to change and test light and dark color schemes in development.</p>




<h3 id="heading-5-buttonstyle-and-button-label">5.  <code>buttonStyle</code> and button label</h3>
<p>Comparing to the old days in <a target="_blank" href="https://developer.apple.com/documentation/uikit">UIKit</a>, constructing reusable buttons in SwiftUI is drastically easier. The <a target="_blank" href="https://developer.apple.com/documentation/swiftui/button">Button view</a> consists of two parts, which are <code>action</code> closure (event to be fired as button is pressed) and <code>label</code> (body of the button). The view can then be chained with a modifier <code>buttonStyle</code>. To learn details about building reusable buttons,I recommend reading <a target="_blank" href="https://alejandromp.com/blog/2019/06/22/swiftui-reusable-button-style/">Alejandro's tutorial</a>, which is comprehensive and useful.</p>
<p>In our customized button components, first step is to create two structs, including <code>TokenButtonLabel</code> and <code>TokenButtonStyle</code>. These two structs are programmed according to the types of buttons we have in design files. For example, there're only two types of labels: icon and text. Each type has an according <code>init</code> function designed with different parameters for new instances.</p>


<p>On the other hand, there're four major types of button styles: circle icon, icon, capsule and text. To follow <code>ButtonStyle</code> protocol, a <code>makeBody</code> func has to be implemented. This function brings us a <code>configuration</code> property, providing a native <code>isPressed</code> value to monitor if the button is pressed or not.</p>


<p>Finally, stacking on top of <code>TokenButtonLabel</code> and <code>TokenButtonStyle</code>, the endpoint of the button component API will be <code>TokenButton</code> - a grouping that wraps content and style of button together, conforming to the button types in visual design system.</p>




<h3 id="heading-6-anyview-as-wrapper">6. <code>AnyView</code> as wrapper</h3>
<p>As we're dealing with the <code>makeBody</code> function brought by <code>ButtonStyle</code> protocol, we found a useful tip to work with <code>View</code>. To store a view in a variable, the type annotation could be indicated as <code>AnyView</code>, which works as a general container of views in SwiftUI.</p>
<p>In our case, because we want to add the opacity modifier to <code>configuration.label</code> to all types of buttons, instead of doing so repeatedly in each <code>switch</code> case, it makes more sense to chain the modifier at the end altogether. We can achieve this pattern by using the advantage of <code>AnyView</code> in this way:</p>




<h3 id="heading-7-build-view-modifier-with-mutating-function">7. Build view modifier with <code>mutating</code> function</h3>
<p>To update styles of the buttons dynamically, we can build our own modifier. First instantiate customized mutable state properties in view, and then create a <code>mutating</code> function which returns a <code>Self</code> type after updating the target state property.</p>




<h3 id="heading-8-tricky-border-style">8. Tricky border style</h3>
<p>One drawback of SwiftUI is styling a circle shape with circular border is not straightforward at all. I struggled for a while, and finally found a <a target="_blank" href="https://stackoverflow.com/questions/57269651/add-a-border-with-cornerradius-to-an-image-in-swiftui-xcode-beta-5">solution here on StackOverflow</a>. A <code>clipShape</code> and an <code>overlay</code> modifier are required to make it work.</p>




<hr>
<h2 id="heading-conclusion">Conclusion</h2>
<p>SwiftUI is an incredible improvement Apple makes. Though flaws still exist, building a robust and flexible design system with it, and furthermore complicated UI in iOS is way efficient than ever. I hope this article is helpful for any iOS team trying to build UI, and always welcome to any feedbacks!</p>
<p>? Read more of my works at <a target="_blank" href="https://www.vinceshao.com">vinceshao.com</a> / Follow me on <a target="_blank" href="https://twitter.com/vincemingpushao">Twitter</a> or <a target="_blank" href="https://www.linkedin.com/in/vinceshao/">LinkedIn</a></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
