<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Brahim ELM on Medium]]></title>
        <description><![CDATA[Stories by Brahim ELM on Medium]]></description>
        <link>https://medium.com/@siempay?source=rss-ca25fe18bc5b------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*hEJ_jOBOBgdtT41D9dGIPg.jpeg</url>
            <title>Stories by Brahim ELM on Medium</title>
            <link>https://medium.com/@siempay?source=rss-ca25fe18bc5b------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 10:53:32 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@siempay/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[SwiftUI Button Tap Area Issue: A Complete Guide]]></title>
            <link>https://siempay.medium.com/swiftui-button-tap-area-issue-a-complete-guide-2421166d6291?source=rss-ca25fe18bc5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/2421166d6291</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Brahim ELM]]></dc:creator>
            <pubDate>Fri, 13 Feb 2026 16:07:39 GMT</pubDate>
            <atom:updated>2026-02-16T13:57:09.556Z</atom:updated>
            <content:encoded><![CDATA[<h4>SwiftUI determines what gets tapped using a process called <strong>hit testing…</strong></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*GlMdH2cDETHmTlqV" /><figcaption>Photo by <a href="https://unsplash.com/@glyamin?utm_source=medium&amp;utm_medium=referral">Georgiy Lyamin</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>The Problem</h3><p>When building card-based UIs in SwiftUI, a common issue occurs where <strong>tap gestures extend beyond the visible content</strong>, causing unexpected behavior like tapping one UI element accidentally triggers another nearby element.</p><h3>Understanding SwiftUI’s Hit Testing</h3><p>SwiftUI determines what gets tapped using a process called <strong>hit testing</strong>, which has some non-obvious rules:</p><h3>1. .clipShape() vs Tap Area</h3><pre>// ❌ WRONG: clipShape only clips VISUALS, not tap area<br>ZStack {<br>    RoundedRectangle(cornerRadius: 16)<br>        .fill(Color.blue)<br>    <br>    Text(&quot;Content&quot;)<br>}<br>.frame(height: 160)<br>.clipShape(RoundedRectangle(cornerRadius: 16))  // Only clips visuals!<br>.onTapGesture { /* This can receive taps from the entire 160pt frame */ }</pre><p><strong>Problem</strong>: The view’s <strong>frame</strong> (rectangular boundary) remains the tap target, even though visually it’s rounded.</p><h3>2. .shadow() Extends Tap Area</h3><pre>// ❌ WRONG: Shadow extends the tappable area<br>VStack { /* content */ }<br>    .shadow(radius: 4, x: 0, y: 2)  // Shadow pixels become tappable!<br>    .onTapGesture { }</pre><p><strong>Problem</strong>: SwiftUI considers the shadow part of the view’s bounds, so taps on the shadow (including areas above/below the visible content) register.</p><h3>3. ZStack with Shapes Forward Taps</h3><pre>// ❌ WRONG: Background shape expands tap area<br>ZStack {<br>    RoundedRectangle(cornerRadius: 16)<br>        .fill(Color.blue)<br>        .frame(height: 160)  // This shape fills the entire height<br>    <br>    VStack { <br>        Text(&quot;Content&quot;)  // This might be shorter<br>    }<br>}<br>.onTapGesture { /* Taps anywhere in 160pt ZStack trigger this */ }</pre><p><strong>Problem</strong>: The RoundedRectangle expands to fill the frame, making the entire ZStack tappable, even where there&#39;s no visible content.</p><h3>4. .onTapGesture vs Button</h3><pre>// ⚠️ CAUTION: onTapGesture responds to taps on entire frame<br>VStack { /* content */ }<br>    .frame(height: 160)<br>    .onTapGesture { }  // Entire 160pt height is tappable<br><br><br>// ✅ BETTER: Button only responds to taps on its content<br>Button(action: { }) {<br>    VStack { /* content */ }<br>        .frame(maxHeight: .infinity)  // Must explicitly fill<br>}<br>.frame(height: 160)</pre><p><strong>Key Difference</strong>:</p><ul><li>.onTapGesture makes the <strong>entire frame</strong> tappable</li><li>Button only makes its <strong>visible content</strong> tappable (unless you explicitly fill the space)</li></ul><h3>The Solution: Correct SwiftUI Button Pattern</h3><h3>✅ Pattern 1: Button with Explicit Content Filling</h3><pre>Button(action: {<br>    print(&quot;Card tapped&quot;)<br>}) {<br>    VStack(spacing: 12) {<br>        Image(&quot;icon&quot;)<br>            .resizable()<br>            .frame(height: 98)<br>        <br>        Text(&quot;Title&quot;)<br>            .font(.headline)<br>    }<br>    .padding(.horizontal, 16)<br>    .frame(maxWidth: .infinity, maxHeight: .infinity)  // ← Key: Fill the space<br>}<br>.buttonStyle(.plain)  // Remove default button styling<br>.frame(height: 160)<br>.background(<br>    RoundedRectangle(cornerRadius: 16)<br>        .fill(Color.blue)<br>)<br>.clipShape(RoundedRectangle(cornerRadius: 16))</pre><p><strong>Why this works</strong>:</p><ol><li>✅ Button content explicitly fills the 160pt height with .frame(maxWidth: .infinity, maxHeight: .infinity)</li><li>✅ Background is applied <strong>after</strong> the button, so it’s decoration, not a separate tappable shape</li><li>✅ .clipShape() constrains both visuals AND tap area to the rounded rectangle</li><li>✅ .buttonStyle(.plain) removes default button appearance</li></ol><h3>✅ Pattern 2: Using .contentShape() with .onTapGesture</h3><p>If you must use .onTapGesture, add .contentShape():</p><pre>VStack { /* content */ }<br>    .frame(height: 160)<br>    .background(Color.blue)<br>    .clipShape(RoundedRectangle(cornerRadius: 16))<br>    .contentShape(RoundedRectangle(cornerRadius: 16))  // ← Constrains tap area<br>    .onTapGesture { }</pre><p><strong>Why this works</strong>: .contentShape() explicitly defines the <strong>hit-testing area</strong>, overriding the default rectangular frame.</p><h3>Common Mistakes to Avoid</h3><h3>❌ Mistake 1: ZStack with Competing Tap Targets</h3><pre>// DON&#39;T DO THIS<br>ZStack {<br>    RoundedRectangle(cornerRadius: 16)<br>        .fill(Color.blue)<br>        .onTapGesture { }  // ← This captures taps for entire ZStack!<br>    <br>    Button(action: { }) {<br>        VStack { /* smaller content */ }<br>    }<br>}</pre><p><strong>Fix</strong>: Don’t put tappable shapes and buttons as siblings in a ZStack. Make the button the primary view with background as a modifier.</p><h3>❌ Mistake 2: Shadow Inside Button/Gesture Area</h3><pre>// DON&#39;T DO THIS<br>Button(action: { }) {<br>    VStack { /* content */ }<br>        .shadow(radius: 4, x: 0, y: 2)  // ← Shadow extends tap area<br>}</pre><p><strong>Fix</strong>: Apply shadow <strong>outside</strong> the button:</p><pre>Button(action: { }) {<br>    VStack { /* content */ }<br>}<br>.shadow(radius: 4, x: 0, y: 2)  // ← Shadow is decoration, not part of tap area</pre><h3>❌ Mistake 3: Not Filling Button Content</h3><pre>// DON&#39;T DO THIS<br>Button(action: { }) {<br>    VStack { /* 100pt of content */ }<br>}<br>.frame(height: 160)  // Button content is 100pt, but frame is 160pt</pre><p><strong>Problem</strong>: The 60pt gap might still respond to taps!</p><p><strong>Fix</strong>:</p><pre>Button(action: { }) {<br>    VStack { /* 100pt of content */ }<br>        .frame(maxHeight: .infinity)  // Fill the available space<br>}<br>.frame(height: 160)</pre><h3>Best Practices Checklist</h3><p>When creating tappable cards/buttons:</p><ol><li>✅ <strong>Use </strong><strong>Button over </strong><strong>.onTapGesture</strong> when possible</li><li>✅ <strong>Make button content fill the frame</strong> with .frame(maxWidth: .infinity, maxHeight: .infinity)</li><li>✅ <strong>Apply backgrounds/borders as modifiers</strong> on the button, not as separate ZStack layers</li><li>✅ <strong>Apply shadows outside</strong> the button/gesture</li><li>✅ <strong>Use </strong><strong>.contentShape()</strong> if you must use .onTapGesture to explicitly define tap area</li><li>✅ <strong>Use </strong><strong>.buttonStyle(.plain)</strong> to remove default button styling</li><li>✅ <strong>Test tap boundaries</strong> in previews with visual debugging (like the red background we used)</li></ol><h3>Visual Debugging Technique</h3><p>Add a colored background to see the actual tap area:</p><pre>Button(action: { }) {<br>    VStack { /* content */ }<br>        .frame(maxWidth: .infinity, maxHeight: .infinity)<br>}<br>.background(Color.red.opacity(0.3))  // ← See the actual tap area</pre><p>This reveals mismatches between visual appearance and tap boundaries.</p><h3>Summary</h3><p>The core principle: <strong>SwiftUI’s tap area = the view’s frame, not its visual appearance</strong>. Always explicitly control:</p><ul><li>The content size (with .frame(maxWidth:maxHeight:))</li><li>The tap area (with Button or .contentShape())</li><li>Decoration order (backgrounds, shadows applied as modifiers, not siblings)</li></ul><p>Following these patterns prevents ghost taps and ensures users tap exactly what they see.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2421166d6291" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SwiftUI: 10 Functional Roles of Overlay + Rectangle]]></title>
            <link>https://siempay.medium.com/swiftui-10-functional-roles-of-overlay-rectangle-358c7fa1364d?source=rss-ca25fe18bc5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/358c7fa1364d</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swiftui]]></category>
            <dc:creator><![CDATA[Brahim ELM]]></dc:creator>
            <pubDate>Thu, 15 Jan 2026 18:20:26 GMT</pubDate>
            <atom:updated>2026-01-16T19:23:42.875Z</atom:updated>
            <content:encoded><![CDATA[<h4>A quick “cheatsheet” of everything from shimmer effects and custom progress bars to the “masking trick” for partial borders.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OWFEArocoxpSvRYB99Mg8A.png" /></figure><p>Lately, I’ve been leaning heavily into .overlay() paired with Rectangle shapes. It’s cleaner, it respects the parent view’s frame, and honestly it’s much more powerful than most people realize. Here are 15 ways I use this combo to keep my SwiftUI code lean.</p><h3>What’s in this Guide</h3><p>In this article, we’re going to move beyond simple “borders.” We will explore how the .overlay() + Rectangle combo solves real-world engineering problems:</p><ol><li><strong>The Tap-Helper:</strong> Make tiny icons easy to click without moving your UI.</li><li><strong>The Dimmer:</strong> Fade out the background so your popups actually pop.</li><li><strong>The Sharp Line:</strong> Forget messy dividers; use a 1px rectangle for perfect borders.</li><li><strong>The Progress Fill:</strong> The easiest way to build a loading bar that stays in its lane.</li><li><strong>The Ghost Box:</strong> Hide empty text with “skeleton” blocks while data loads.</li><li><strong>The Text Guard:</strong> Add a quick gradient so white text doesn’t vanish on bright photos.</li><li><strong>The Glow-Up:</strong> Switch on a colored border to show exactly what’s selected.</li><li><strong>The Tag Pinner:</strong> Stick “Sale” or “New” badges onto cards without the headache.</li><li><strong>The Shimmer:</strong> Add that “expensive” moving light effect to loading screens.</li><li><strong>The Edge Cutter:</strong> Mix and match sharp and round corners for a custom look.</li></ol><h3>1. The Hit-Box (Interaction)</h3><p>The most common mistake for juniors is making buttons too small. An invisible Rectangle in an overlay creates a perfect tap target.</p><pre>Image(systemName: &quot;pencil&quot;)<br>    .overlay(<br>        Rectangle()<br>            .fill(.black.opacity(0.0001)) <br>            .frame(width: 44, height: 44)<br>    )<br>    .onTapGesture { print(&quot;Tapped!&quot;) }</pre><h3>2. The Scrim (Focus)</h3><p>When a modal appears, you need to dim the background. A Rectangle overlay is the cleanest way to do this.</p><pre>MainContentView()<br>    .overlay(<br>        isShowingDimmer ? Rectangle().fill(.black.opacity(0.4)) : nil<br>    )</pre><h3>3. The Precision Divider (Layout)</h3><p>Divider() often adds unwanted padding. A 1px Rectangle pinned to the bottom of an overlay gives you total control.</p><pre>VStack { Text(&quot;Item&quot;) }<br>    .overlay(Rectangle().frame(height: 1).foregroundColor(.gray), alignment: .bottom)</pre><h3>4. The Progress Track (Data Visualization)</h3><p>Using an overlay ensures the “fill” bar never exceeds the size of the “track” bar.</p><pre>Rectangle()<br>    .fill(.gray.opacity(0.2))<br>    .frame(height: 8)<br>    .overlay(<br>        GeometryReader { geo in<br>            Rectangle()<br>                .fill(.blue)<br>                .frame(width: geo.size.width * 0.6)<br>        }, alignment: .leading<br>    )</pre><h3>5. The Skeleton Loader (Loading States)</h3><p>Use a Rectangle to &quot;block out&quot; content while data is fetching.</p><pre>Text(&quot;Username&quot;)<br>    .overlay(isLoading ? RoundedRectangle(cornerRadius: 4).fill(.gray.opacity(0.3)) : nil)</pre><h3>6. The Text Protector (Readability)</h3><p>Protect your text from “busy” image backgrounds with a gradient Rectangle.</p><pre>Image(&quot;bg&quot;)<br>    .overlay(Rectangle().fill(LinearGradient(colors: [.clear, .black], startPoint: .top, endPoint: .bottom)))</pre><h3>7. The State Indicator (Selection)</h3><p>Instead of changing background colors, use a stroke overlay to show selection clearly.</p><pre>CardView()<br>    .overlay(RoundedRectangle(cornerRadius: 12).stroke(isSelected ? .blue : .clear, lineWidth: 2))</pre><h3>8. The Badge Anchor (Information)</h3><p>Perfect for “New” or “Sale” tags that need to sit on top of a component.</p><p>Swift</p><pre>ProductImage()<br>    .overlay(Text(&quot;NEW&quot;).background(Capsule().fill(.red)), alignment: .topTrailing)</pre><h3>9. The Shimmer Effect (Animation)</h3><p>A sliding gradient Rectangle creates that premium &quot;loading&quot; feel.</p><pre>Rectangle()<br>    .fill(.gray.opacity(0.2))<br>    .overlay(<br>        Rectangle()<br>            .fill(LinearGradient(colors: [.clear, .white, .clear], startPoint: .leading, endPoint: .trailing))<br>            .offset(x: offset)<br>    ).clipped()</pre><h3>10. The Style Clipper (Modern Design)</h3><p>Use UnevenRoundedRectangle to create unique UI shapes that stand out.</p><pre>Rectangle()<br>    .fill(.blue)<br>    .overlay(UnevenRoundedRectangle(topLeadingRadius: 20).stroke(.white, lineWidth: 2))</pre><h3>Conclusion</h3><p>As a junior developer, it’s easy to over-complicate your view hierarchy with nested stacks. Mastering the .overlay() + Rectangle combo allows you to write flatter, more performant code while maintaining precise control over your UI&#39;s interaction and state.</p><p><strong>Which of these roles are you going to implement in your next project? Let me know in the comments!</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=358c7fa1364d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What is Async Test Pollution ?]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://siempay.medium.com/what-is-async-test-pollution-53c2b1bd8248?source=rss-ca25fe18bc5b------2"><img src="https://cdn-images-1.medium.com/max/2600/0*1IaK3xTFo6qU5ia5" width="5184"></a></p><p class="medium-feed-snippet">The Hidden Saboteur in My Test Suite</p><p class="medium-feed-link"><a href="https://siempay.medium.com/what-is-async-test-pollution-53c2b1bd8248?source=rss-ca25fe18bc5b------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://siempay.medium.com/what-is-async-test-pollution-53c2b1bd8248?source=rss-ca25fe18bc5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/53c2b1bd8248</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Brahim ELM]]></dc:creator>
            <pubDate>Sat, 19 Jul 2025 16:47:11 GMT</pubDate>
            <atom:updated>2025-07-19T16:47:11.714Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[What is Sendable in Swift ? Concurrency Without Data Races]]></title>
            <link>https://siempay.medium.com/what-is-sendable-in-swift-concurrency-without-data-races-0c64130bb3d1?source=rss-ca25fe18bc5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/0c64130bb3d1</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <dc:creator><![CDATA[Brahim ELM]]></dc:creator>
            <pubDate>Thu, 13 Mar 2025 10:02:27 GMT</pubDate>
            <atom:updated>2025-03-13T10:02:27.403Z</atom:updated>
            <content:encoded><![CDATA[<h3>What is Sendable in Swift ? Concurrency Without Data Races</h3><h4>Learn how Sendable ensures thread safety in Swift concurrency, when to use it, and how to avoid common pitfalls.Sendable in Swift</h4><p>Sendable is a protocol introduced in Swift to ensure that types can be safely passed across concurrency domains (e.g., between tasks in Swift concurrency).</p><h3>1. What Does Sendable Do?</h3><p>It marks a type as <strong>safe to be shared</strong> across multiple threads, ensuring no <strong>data races</strong> in concurrent environments.</p><h3>2. When to Use It?</h3><ul><li>When working with <strong>Swift Concurrency</strong> (async/await, Task, Actor).</li><li>When a type is used across different <strong>isolated execution contexts</strong> (like different tasks or actors).</li></ul><h3>3. Example Usage</h3><h4>✅ Sendable Struct (Automatic Conformance)</h4><p>Value types (structs, enums) that contain only Sendable types automatically conform to Sendable:</p><pre>struct User: Sendable {<br>    let name: String<br>    let age: Int<br>}</pre><h4>❌ Non-Sendable Class (Reference Types Need Manual Handling)</h4><p>Classes do not conform to Sendable by default, because they introduce shared mutable state.</p><pre>class User { // ❌ Not Sendable<br>    var name: String<br>    init(name: String) {<br>        self.name = name<br>    }<br>}</pre><p>To fix this, either:</p><ol><li><strong>Make it immutable (</strong><strong>final + </strong><strong>let properties)</strong></li><li><strong>Mark it explicitly </strong><strong>@unchecked Sendable (⚠️ You promise it&#39;s thread-safe)</strong></li></ol><pre>final class User: @unchecked Sendable {<br>    let name: String<br>    init(name: String) {<br>        self.name = name<br>    }<br>}</pre><h3>4. Sendable and Actors</h3><p>Actors <strong>isolate state</strong> and are implicitly Sendable, so they can be safely used across threads.</p><pre>actor Counter {<br>    private var value = 0<br>    func increment() { value += 1 }<br>}</pre><h3>5. Common Errors</h3><p>If a type is used in an async function or within an actor and is <strong>not</strong> Sendable, Swift will give an error like:<br> 🚨 <em>&quot;Type &#39;X&#39; is not Sendable; this is an error in Swift concurrency.&quot;</em></p><h3>6. Summary</h3><p>Sendable is a crucial tool for writing safe concurrent code in Swift. By marking types as Sendable, you prevent data races and ensure smooth execution across multiple threads. Structs and enums are usually safe by default, while classes require extra care. Understanding and using Sendable correctly will make your Swift concurrency code more reliable and efficient. 🚀</p><p>Follow for more …</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0c64130bb3d1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Can a 1B Model Beat a 405B Model? The Future of Small LLMs in a Compute-Optimized World ]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://siempay.medium.com/can-a-1b-model-beat-a-405b-model-the-future-of-small-llms-in-a-compute-optimized-world-9ef14ad66d04?source=rss-ca25fe18bc5b------2"><img src="https://cdn-images-1.medium.com/max/2600/1*0Ps2Vd214rIB5Va-L98l_Q@2x.jpeg" width="3240"></a></p><p class="medium-feed-snippet">Introduction: Why LLM Architectures Matter</p><p class="medium-feed-link"><a href="https://siempay.medium.com/can-a-1b-model-beat-a-405b-model-the-future-of-small-llms-in-a-compute-optimized-world-9ef14ad66d04?source=rss-ca25fe18bc5b------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://siempay.medium.com/can-a-1b-model-beat-a-405b-model-the-future-of-small-llms-in-a-compute-optimized-world-9ef14ad66d04?source=rss-ca25fe18bc5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/9ef14ad66d04</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Brahim ELM]]></dc:creator>
            <pubDate>Sat, 15 Feb 2025 20:40:29 GMT</pubDate>
            <atom:updated>2025-02-15T20:40:29.065Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[The best code is no code, but when you must, make it composable]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://siempay.medium.com/the-best-code-is-no-code-but-when-you-must-make-it-composable-0056dc1a0b57?source=rss-ca25fe18bc5b------2"><img src="https://cdn-images-1.medium.com/max/2600/0*Ynj7GdWjfLN4iOeq" width="5849"></a></p><p class="medium-feed-snippet">&#x1F3D7;&#xFE0F; Embracing the Composable Architecture: A Swift Developer&#x2019;s Guide to Sanity</p><p class="medium-feed-link"><a href="https://siempay.medium.com/the-best-code-is-no-code-but-when-you-must-make-it-composable-0056dc1a0b57?source=rss-ca25fe18bc5b------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://siempay.medium.com/the-best-code-is-no-code-but-when-you-must-make-it-composable-0056dc1a0b57?source=rss-ca25fe18bc5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/0056dc1a0b57</guid>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[architecture]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Brahim ELM]]></dc:creator>
            <pubDate>Thu, 13 Feb 2025 14:52:18 GMT</pubDate>
            <atom:updated>2025-02-13T14:52:18.693Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Don’t Chase Patterns, Focus on Solving Problems]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/2-minutes-read-tip/dont-chase-patterns-focus-on-solving-problems-d5f143c3486e?source=rss-ca25fe18bc5b------2"><img src="https://cdn-images-1.medium.com/max/2600/1*3v2NWygiVP0954ZcWlcwYQ@2x.jpeg" width="3240"></a></p><p class="medium-feed-snippet">A word on architectures in iOS and mobile development in general </p><p class="medium-feed-link"><a href="https://medium.com/2-minutes-read-tip/dont-chase-patterns-focus-on-solving-problems-d5f143c3486e?source=rss-ca25fe18bc5b------2">Continue reading on iOS Senior Tips »</a></p></div>]]></description>
            <link>https://medium.com/2-minutes-read-tip/dont-chase-patterns-focus-on-solving-problems-d5f143c3486e?source=rss-ca25fe18bc5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/d5f143c3486e</guid>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Brahim ELM]]></dc:creator>
            <pubDate>Sun, 15 Sep 2024 19:46:35 GMT</pubDate>
            <atom:updated>2024-09-15T19:46:35.948Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Secure Your iOS App Like a Pro: Top 7 Risks You Most Likely Overlook]]></title>
            <link>https://siempay.medium.com/secure-your-ios-app-like-a-pro-top-7-risks-you-most-likely-overlook-263f6f9aac1a?source=rss-ca25fe18bc5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/263f6f9aac1a</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Brahim ELM]]></dc:creator>
            <pubDate>Tue, 10 Sep 2024 07:23:34 GMT</pubDate>
            <atom:updated>2024-09-10T07:23:34.394Z</atom:updated>
            <content:encoded><![CDATA[<h4>Critical Security Vulnerabilities That Could Be Hiding in Your iOS App</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*o-hD-zFZPesvjWaO" /><figcaption>Photo by <a href="https://unsplash.com/@piggybank?utm_source=medium&amp;utm_medium=referral">PiggyBank</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Even the most skilled iOS developers can fall into the trap of prioritizing features and design over security. Yet, leaving critical vulnerabilities unchecked can compromise both your app and its users. From mishandling sensitive data to neglecting proper input validation, there are risks that many developers don’t realize they’re overlooking. In this article I will highlight the top seven security risks you’re most likely to miss — and how to address them like a true pro will be coming in future articles. Don’t forget to follow for more.</p><h4>The Underestimated Importance of HTTPS and App Transport Security</h4><p>Many developers assume their app is secure if it simply communicates over HTTPS, but App Transport Security (ATS) enforces additional security standards like requiring SSL certificates that meet certain criteria. Skipping ATS or adding too many exceptions can leave your app vulnerable to man-in-the-middle attacks, compromising user data. Always review ATS configurations to make sure your app’s connections are fully secure.</p><p><em>Source: Apple Developer Documentation</em></p><h4>The Hidden Risk of Insecure Data Storage</h4><p>A common mistake developers make is storing sensitive data, like API tokens or user credentials, in UserDefaults. What most don’t realize is that UserDefaults is not encrypted, making it a potential target for attackers. Instead, sensitive data should always be stored in the iOS Keychain, which is designed to store data securely with encryption, even across app restarts.</p><p><em>Source: iOS Security Guide, Apple</em></p><h4>The Overlooked Need for Secure Backups</h4><p>Most developers don’t consider how their app data is handled during backups. By default, data stored in Documents or Cache directories may be included in iCloud backups, potentially exposing sensitive information. Use NSFileProtection to encrypt files on disk, and set the appropriate flags to ensure sensitive data isn’t backed up to iCloud unless it’s necessary for the user.</p><p><em>Source: iOS Security White Paper, Apple</em></p><h4>The Overlooked Threat of Jailbroken Devices</h4><p>Jailbroken devices pose a security risk for your app that often goes unnoticed. By bypassing iOS’s built-in security, these devices can compromise data stored in your app or bypass in-app purchases. Detecting if your app is running on a jailbroken device and limiting its functionality in such cases can prevent many security vulnerabilities from being exploited.</p><p><em>Source: OWASP Mobile Security Project</em></p><h4>The Silent Danger of Hard-Coding API Keys</h4><p>Hard-coding API keys directly into your app’s code may seem convenient, but it’s a major security flaw. When you hard-code keys, they can be easily extracted from your app’s binary by attackers. Instead, use secure methods like storing keys in the Keychain or fetching them dynamically from a secure server, where you can rotate them as needed for added security.</p><p><em>Source: OWASP Mobile Security Guide</em></p><h4>The Hidden Vulnerability of Insufficient Input Validation</h4><p>Even though iOS apps are generally considered secure, attackers can still exploit poorly validated inputs. If your app interacts with APIs or user-generated content, failing to properly validate inputs (like rejecting malformed URLs or restricting field lengths) can open your app to injection attacks. Always sanitize and validate user input on both the client and server sides to avoid this vulnerability.</p><p><em>Source: Apple Developer Documentation</em></p><h4>The Risk of Over-Exposing App Permissions</h4><p>Granting too many permissions to an app — such as access to photos, location, or contacts — without clear purpose not only annoys users but opens potential privacy risks. Many users don’t realize this, but improperly requested permissions can also flag your app for rejection during the App Store review process. Always follow the least privilege principle, requesting only the permissions your app absolutely needs to function.</p><p><em>Source: App Store Review Guidelines</em></p><h4>Conclusion</h4><p>Securing your app doesn’t stop at flawless design and smooth functionality; it requires a vigilant approach to identifying and resolving hidden security risks. By taking the time to address these seven often-overlooked vulnerabilities, you can elevate your app’s security to a professional level. Don’t let these silent threats undermine your hard work — secure your iOS app like a pro and give your users the protection they deserve.</p><p>Don’t forget to follow for next coming articles, and check <a href="https://howtoinswift.tech/">howtoinswift.tech</a></p><p>Question for you: As an iOS Developer, what is the flow you had experienced?</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=263f6f9aac1a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[80% of Programmers Aren’t Happy: A Philosophical Exploration]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://siempay.medium.com/80-of-programmers-arent-happy-a-philosophical-exploration-360fa2ad4725?source=rss-ca25fe18bc5b------2"><img src="https://cdn-images-1.medium.com/max/2600/0*8osIccL_8o2zqwE0" width="4000"></a></p><p class="medium-feed-snippet">Why Programmers are Unhappy and How to Break Free</p><p class="medium-feed-link"><a href="https://siempay.medium.com/80-of-programmers-arent-happy-a-philosophical-exploration-360fa2ad4725?source=rss-ca25fe18bc5b------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://siempay.medium.com/80-of-programmers-arent-happy-a-philosophical-exploration-360fa2ad4725?source=rss-ca25fe18bc5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/360fa2ad4725</guid>
            <category><![CDATA[lifestyle]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Brahim ELM]]></dc:creator>
            <pubDate>Fri, 02 Aug 2024 10:16:52 GMT</pubDate>
            <atom:updated>2024-08-02T10:16:52.080Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[5 Weird ADHD Behaviors No One Understands]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://siempay.medium.com/5-weird-adhd-behaviors-no-one-understands-e835babbecb1?source=rss-ca25fe18bc5b------2"><img src="https://cdn-images-1.medium.com/max/2600/0*kEoJmnlLy9XopN74" width="4000"></a></p><p class="medium-feed-snippet">Actually it&#x2019;s just such a strange condition, like it really doesn&#x2019;t make any sense.</p><p class="medium-feed-link"><a href="https://siempay.medium.com/5-weird-adhd-behaviors-no-one-understands-e835babbecb1?source=rss-ca25fe18bc5b------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://siempay.medium.com/5-weird-adhd-behaviors-no-one-understands-e835babbecb1?source=rss-ca25fe18bc5b------2</link>
            <guid isPermaLink="false">https://medium.com/p/e835babbecb1</guid>
            <category><![CDATA[adhd]]></category>
            <category><![CDATA[personal-development]]></category>
            <category><![CDATA[self-improvement]]></category>
            <category><![CDATA[self]]></category>
            <category><![CDATA[psychology]]></category>
            <dc:creator><![CDATA[Brahim ELM]]></dc:creator>
            <pubDate>Sun, 30 Jun 2024 12:33:18 GMT</pubDate>
            <atom:updated>2024-06-30T12:33:18.808Z</atom:updated>
        </item>
    </channel>
</rss>