<?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 Mohammad Azam on Medium]]></title>
        <description><![CDATA[Stories by Mohammad Azam on Medium]]></description>
        <link>https://medium.com/@azamsharp?source=rss-2300266301b3------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*Wfeql4CDzQz6fq15jGfmQA.png</url>
            <title>Stories by Mohammad Azam on Medium</title>
            <link>https://medium.com/@azamsharp?source=rss-2300266301b3------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 12 Nov 2026 08:20:54 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@azamsharp/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[Learning to Learn in the Age of AI]]></title>
            <link>https://azamsharp.medium.com/learning-to-learn-in-the-age-of-ai-11116223d788?source=rss-2300266301b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/11116223d788</guid>
            <category><![CDATA[chatgpt]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[claude]]></category>
            <category><![CDATA[vibe-coding]]></category>
            <category><![CDATA[coding]]></category>
            <dc:creator><![CDATA[Mohammad Azam]]></dc:creator>
            <pubDate>Sat, 07 Nov 2026 02:24:00 GMT</pubDate>
            <atom:updated>2026-11-07T02:24:00.371Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZDB5x7AhyDGTdrcy2Ay8YA.png" /><figcaption>Learning to Learn in the Age of AI</figcaption></figure><p>I started learning programming back in the early 90s. The World Wide Web had just been introduced, but it would still be a few years before I had access to the internet.</p><p>Luckily, books were available, and I spent most of my time reading programming books and manually typing code, one instruction at a time, into the editor. One of the first programming languages I learned was GW BASIC. I still remember creating a simple program that displayed a face that would switch between happy and sad.</p><p>A few years later, I finally got access to the internet, and a few years after that, Google arrived. Technology was advancing rapidly, but developers still had to struggle to find and implement solutions.</p><p>For example, imagine you were building an application that displayed a map, and you wanted to cluster different markers together. You would have to read documentation, search Stack Overflow, or explore other online resources to figure out how to implement it.</p><p>Sometimes, you would find the exact answer you were looking for. Other times, you would find something similar and have to think through how to apply that solution to your particular situation.</p><p>Fast forward to today, and AI can generate an entire implementation in just a few seconds. This is great because you save a lot of time and suddenly become a 10X developer. But at the same time, you may not have struggled at all. All it took was a single prompt, and your work was done.</p><p>But if AI does all the work, what exactly are we learning?</p><p>I have been teaching in one form or another since before 2002, and one thing I strongly believe is that if you are not struggling, you are not learning. This is especially true when you are trying to learn something new.</p><p>When I was teaching at a physical campus, I would always tell my students to break down a problem into smaller tasks. For each task, give yourself 15 to 20 minutes of pure struggle before asking for help.</p><p>That is when real learning happens.</p><p>You might try nine different approaches, and none of them work. Finally, on your tenth attempt, you find a solution. But you did not fail nine times. You discovered nine different approaches that did not work.</p><p>As Thomas Edison is often quoted as saying:</p><blockquote><em>I have not failed. I’ve just found 10,000 ways that won’t work.</em></blockquote><p>Today, AI has made it easier than ever to avoid that struggle. Even worse, some developers have stopped reviewing AI generated code. They simply assume that because AI wrote the code and it works, it must be good.</p><p>Unfortunately, my experience has been that while AI is very good at generating code, it does not always account for the long term consequences of its decisions. It can produce a working implementation without considering how that implementation will affect the architecture, maintainability, or future development of the application.</p><p>Generating code is not the same as engineering software.</p><p>So, should we stop using AI?</p><p><strong>No</strong>.</p><p>AI is a powerful technology, but with great power comes great responsibility. We should use AI to enhance and amplify our learning instead of replacing it.</p><p>Instead of asking AI to generate the complete solution, ask it to point you toward the documentation for the framework you are trying to learn. You can even explicitly tell AI not to provide a solution, but instead to share relevant code samples from the documentation.</p><p>You can also ask for a hint rather than working code. That hint might give you just enough information to investigate further and move one step closer to solving the problem yourself.</p><p>There is also an important difference between using AI to become more productive and using AI to become a better programmer.</p><p>We often measure the success of AI by how much time it saves us. But when it comes to learning, saving time should not always be the goal. Sometimes, spending an hour understanding a problem is more valuable than solving it in five minutes.</p><p>One analogy I find helpful is going to the gym. Imagine hiring a personal trainer, but instead of exercising yourself, you let the trainer lift all the weights while you sit on the sidelines.</p><p>No matter how much your trainer exercises, you are not going to lose weight or build muscle. Your trainer might get stronger, but you won’t.</p><p>The same idea applies to your brain.</p><p>Your brain also needs exercise, and one way to exercise it is by working through problems yourself. You need to think critically about different scenarios, explore possible solutions, and understand how your decisions affect the final implementation.</p><p>This does not mean you should struggle with everything. There is a difference between productive struggle and unnecessary frustration. Spending hours dealing with a configuration issue may not teach you much, but spending time understanding why your application has a race condition can make you a better developer.</p><p>The goal is not to make programming unnecessarily difficult. The goal is to make sure we are still learning.</p><p>The next time you are working on a problem, break it down into smaller tasks. Spend 15 to 20 minutes working through each task before waving the white flag and asking AI for help.</p><p>During that time, you can still use AI to look up references, documentation, code samples, or even ask for hints. Just resist the temptation to ask it to generate the complete solution.</p><p>Those 15 to 20 minutes might feel frustrating, especially when you know AI could solve the problem in seconds. But that struggle is an investment in yourself.</p><p>When I was learning GW BASIC, I spent hours writing simple programs and figuring out why things did not work. Today, AI could generate those same programs in seconds.</p><p>But I don’t consider those hours wasted. They taught me how to think, experiment, solve problems, and keep going when things did not work.</p><p>I am not suggesting that we should stop using AI or go back to the way we programmed in the 90s. I am suggesting that we should be intentional about how we use AI, especially when our goal is to learn.</p><p>There is a great quote that captures this idea perfectly:</p><p>“<em>You can outsource your thinking, but you cannot outsource your understanding.</em>”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/408/0*tXfV2261ePd03fGD.png" /></figure><p><a href="https://azamsharp.school/swiftui-architecture-book.html"><strong>Get the book</strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=11116223d788" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Implementing Server-Side Sorting in SwiftUI]]></title>
            <link>https://azamsharp.medium.com/implementing-server-side-sorting-in-swiftui-62bd82feb8ec?source=rss-2300266301b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/62bd82feb8ec</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[rest-api]]></category>
            <category><![CDATA[swift-programming]]></category>
            <dc:creator><![CDATA[Mohammad Azam]]></dc:creator>
            <pubDate>Sat, 17 Oct 2026 15:32:10 GMT</pubDate>
            <atom:updated>2026-10-17T15:32:10.225Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Jwy8KKO2QPn34sed9sAQ2w.png" /></figure><p>When building applications, it is common to display a list of items and allow users to sort them based on different criteria. For example, in a hotel booking application, users may want to sort hotels by price or guest ratings.</p><p>There are different ways to implement sorting. One approach is to fetch all the records from the server and sort them locally on the client. This works fine for smaller datasets, but as the number of records grows, fetching everything just to sort it is not a good idea. A better approach is to let the server handle sorting and return the results in the requested order.</p><p>In this article, we will learn how to implement server-side sorting using Express.js and SwiftUI. We will start by building an API that supports different sorting options through query parameters. Next, we will implement the SwiftUI client using the @Observable macro to manage our hotel data. Finally, we will create a sorting interface that allows users to select, clear, and confirm their sorting preferences.</p><p>Let’s get started!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/408/0*Pg47svkS0d111UA0.png" /></figure><p><strong>Patterns and Practices for Building Scalable Applications</strong></p><p>A practical guide to building SwiftUI apps that stay clean as they grow.</p><p><a href="https://azamsharp.school/swiftui-architecture-book.html"><strong>Get the book</strong></a></p><h3>Building the Sorting API with Express.js</h3><p>These days, you have countless options when it comes to implementing a server. Even in the Swift ecosystem, you have frameworks like Vapor and Hummingbird. My personal favorite is Express.js, mainly because I have taught it for a long time and I also enjoy the dynamic nature of JavaScript.</p><p>One thing I like about using JavaScript on the server is that I don’t have to create separate DTO objects for every response. I can simply return anonymous objects. I personally like this flexibility.</p><p>For our hotel application, we will implement an API endpoint that allows clients to sort hotels based on different criteria, such as price and guest ratings. The client will specify the sorting option using a query string parameter, and the server will be responsible for sorting the results before returning them.</p><p>Below, you can find the implementation of the /api/hotels route, which supports different sorting options.</p><pre>app.get(&quot;/api/hotels&quot;, (req, res) =&gt; {<br>// get the sort options <br>    const { sort } = req.query<br>    // hotels is a hard-coded list <br>    const sortedHotels = sortHotels(hotels, sort)<br>    res.json(sortedHotels)<br>})<br>const sortHotels = (hotels, sort) =&gt; {<br>    switch (sort) {<br>        case &quot;priceLowToHigh&quot;:<br>            hotels.sort((a, b) =&gt; a.price - b.price)<br>            break<br>        case &quot;priceHighToLow&quot;:<br>            hotels.sort((a, b) =&gt; b.price - a.price)<br>            break<br>        case &quot;guestRating&quot;:<br>            hotels.sort((a, b) =&gt; b.guestRating - a.guestRating);<br>            break<br>    }<br>    return hotels <br>}</pre><p>The query string parameter determines how the hotels are sorted. For example, <a href="http://localhost:8080/api/hotels?sort=priceLowToHigh">http://localhost:8080/api/hotels?sort=priceLowToHigh</a> will return hotels sorted by price in ascending order, from lowest to highest.</p><p>Now that our server is working as expected, we can move on to implementing the SwiftUI client.</p><h3>Building the SwiftUI Hotel App</h3><p>We will start by implementing our HotelStore, which will be responsible for managing the state of hotels along with the business and domain logic associated with them.</p><blockquote><em>Unlike traditional View Models, you don’t need to create a separate HotelStore for each screen. HotelStore is designed around the bounded context of hotel management and can be shared across multiple screens that work with hotel-related entities and operations.</em></blockquote><p>The implementation of HotelStore is shown below:</p><pre>@Observable<br>class HotelStore {<br>    <br>    private(set) var hotels: [Hotel] = []<br>    let httpClient: HTTPClient<br>    <br>    init(httpClient: HTTPClient) {<br>        self.httpClient = httpClient<br>    }<br>    <br>    func loadHotels(sortOption: SortOption? = nil) async throws {<br>        let resource = Resource(url: Constants.URLs.hotels(sort: sortOption), responseType: [Hotel].self)<br>        hotels = try await httpClient.fetch(resource: resource)<br>    }<br>}</pre><p>HotelStore has a dependency on HTTPClient, which is responsible for performing network requests. The loadHotels function also accepts an optional SortOption, allowing us to construct the appropriate URL based on the selected sorting option.</p><p>The Constants.URLs.hotels function is responsible for constructing the URL with the necessary query string parameters. In a future article, we will extend this function to support filtering and pagination.</p><p>Inside our SwiftUI view, we can access HotelStore through the environment.</p><blockquote><em>Another option is to pass HotelStore as a dependency through the initializer. I personally prefer using the environment because I often end up using the same store across multiple screens. Passing the store through the initializer of every screen can become cumbersome.</em></blockquote><p>The implementation of HotelListScreen is shown below:</p><pre>struct HotelListScreen: View {<br>    <br>    @Environment(HotelStore.self) private var hotelStore<br>    @State private var showSortSheet: Bool = false<br>    <br>    @State private var sortOption: SortOption?<br>    <br>    var body: some View {<br>        List {<br>            <br>            HStack {<br>                Spacer()<br>                Button(&quot;Sort&quot;) {<br>                    showSortSheet = true<br>                }<br>            }<br>            <br>            ForEach(hotelStore.hotels) { hotel in<br>                HotelCellView(hotel: hotel)<br>            }<br>        }<br>        .sheet(isPresented: $showSortSheet, content: {<br>            SortView(initialSelection: sortOption, onDone: { option in<br>                sortOption = option<br>                Task { await loadHotels() }<br>            }).presentationDetents([.fraction(0.25)])<br>        })<br>        .task {<br>            await loadHotels()<br>        }.navigationTitle(&quot;Hotels&quot;)<br>    }<br>    <br>    private func loadHotels() async {<br>        do {<br>            try await hotelStore.loadHotels(sortOption: sortOption)<br>        } catch {<br>            print(error.localizedDescription)<br>        }<br>    }<br>}</pre><p>You might be wondering why we pass sortOption to the loadHotels function instead of creating a separate function for sorting. You can definitely take that approach, but I personally prefer this design, which is inspired by the Sequelize ORM in JavaScript.</p><p>The idea is simple. You can call loadHotels without passing any options to fetch the default set of hotels (limited to 10 records by default), or you can provide options to customize the results. As we add more features, the same function will support sorting, filtering, and pagination without requiring separate functions for each operation.</p><p>The user selects the sorting option through SortView. The implementation is shown below:</p><pre>struct SortView: View {<br>    <br>    @State private var selectedSortOption: SortOption?<br>    @Environment(\.dismiss) private var dismiss<br>    <br>    let onDone: (SortOption?) -&gt; Void<br>    <br>    init(initialSelection: SortOption? = nil, onDone: @escaping (SortOption?) -&gt; Void) {<br>        _selectedSortOption = State(initialValue: initialSelection)<br>        self.onDone = onDone<br>    }<br>    <br>    var body: some View {<br>        VStack {<br>            <br>            HStack {<br>                Button(&quot;Close&quot;) {<br>                    dismiss()<br>                }<br>                <br>                Spacer()<br>                <br>                Button(&quot;Clear&quot;) {<br>                    selectedSortOption = nil<br>                }<br>                <br>            }.padding([.bottom], 10)<br>            <br>            ForEach(SortOption.allCases) { sortOption in<br>                Button {<br>                    selectedSortOption = sortOption<br>                } label: {<br>                    HStack {<br>                        Image(systemName: selectedSortOption == sortOption<br>                              ? &quot;largecircle.fill.circle&quot; : &quot;circle&quot;)<br>Text(sortOption.title)<br>                    }<br>                    .frame(maxWidth: .infinity, alignment: .leading)<br>                    .contentShape(Rectangle())<br>                }<br>                .buttonStyle(.plain)<br>            }<br>            <br>            Button(&quot;Done&quot;) {<br>                onDone(selectedSortOption)<br>                dismiss()<br>                <br>            }.frame(maxWidth: .infinity, alignment: .leading)<br>            .padding([.top], 20)<br>            .buttonStyle(.borderedProminent)<br>            <br>        }.padding()<br>    }<br>}</pre><p>The interesting part of this implementation is the use of a closure instead of passing an @Binding from the parent. The main reason I decided not to use @Binding is that I want users to be able to cancel their sorting selections without affecting the currently applied sort option.</p><p>If we directly bind the selected sort option to the parent’s state, every selection will immediately update that state, even if the user decides to cancel.</p><p>One way to solve this is to introduce a separate draftSortOption in the parent and pass it as a binding to SortView. That approach works perfectly fine, but I prefer a simpler solution.</p><p>In our implementation, SortView manages its own temporary selection using @State. When the user taps the Done button, we pass the selected sort option back to the parent through a closure. If the user closes the sheet without tapping Done, the original sort option remains unchanged.</p><h3>Resources</h3><ul><li><a href="https://azamsharp.teachable.com/p/hummingbird-fundamentals">Hummingbird Fundamentals — Build REST APIs in Swift</a></li><li><a href="https://azamsharp.teachable.com/p/swiftui-vapor-full-stack-ios-development-bootcamp">Full Stack iOS Development Using Swift &amp; Vapor</a></li></ul><h3>Conclusion</h3><p>In this article, we learned how to implement server-side sorting in a SwiftUI application. Instead of fetching all the records and sorting them on the client, we delegated the sorting responsibility to the server. This approach becomes especially useful when working with large datasets.</p><p>We also explored how to use @Observable to manage our hotel data and how to build a sorting interface using SwiftUI sheets. One interesting design decision was using a closure instead of @Binding, allowing users to confirm or cancel their selections without immediately updating the parent state.</p><p>In the next article, we will extend our implementation to support server-side filtering and pagination. This will allow users to narrow down their search results and load hotels in smaller batches instead of fetching everything at once.</p><h3>Continue Learning with AzamSharp School</h3><p>Become an AzamSharp School member and get access to more than 250 hours of practical courses covering SwiftUI, SwiftData, testing, architecture, AI, machine learning, and more.</p><p>Your membership also includes access to AzamSharp books, live workshops, office hours, and new content added regularly.</p><p><a href="https://azamsharp.school/">Join AzamSharp School</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=62bd82feb8ec" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Protecting SwiftUI Views with Authentication]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://levelup.gitconnected.com/protecting-swiftui-views-with-authentication-bc0b92f7c892?source=rss-2300266301b3------2"><img src="https://cdn-images-1.medium.com/max/1672/1*R6yv2uLPkFU2P30gdPk5Vw.png" width="1672"></a></p><p class="medium-feed-snippet">Most applications contain a mix of public and protected content. A user may be able to explore the Home or Contact screen without signing&#x2026;</p><p class="medium-feed-link"><a href="https://levelup.gitconnected.com/protecting-swiftui-views-with-authentication-bc0b92f7c892?source=rss-2300266301b3------2">Continue reading on Level Up Coding »</a></p></div>]]></description>
            <link>https://levelup.gitconnected.com/protecting-swiftui-views-with-authentication-bc0b92f7c892?source=rss-2300266301b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/bc0b92f7c892</guid>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[swift-programming]]></category>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[ios-development]]></category>
            <dc:creator><![CDATA[Mohammad Azam]]></dc:creator>
            <pubDate>Sat, 29 Aug 2026 14:15:52 GMT</pubDate>
            <atom:updated>2026-08-31T14:13:11.597Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Building Testable SwiftData Applications]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/ios-os-x-development/building-testable-swiftdata-applications-48af6ef2030d?source=rss-2300266301b3------2"><img src="https://cdn-images-1.medium.com/max/1600/1*kL8NTkxVn3MNTR21hwmQ7A.png" width="1600"></a></p><p class="medium-feed-snippet">SwiftData makes it incredibly easy to create, save, and fetch models. That convenience can also make it tempting to write unit tests that&#x2026;</p><p class="medium-feed-link"><a href="https://medium.com/ios-os-x-development/building-testable-swiftdata-applications-48af6ef2030d?source=rss-2300266301b3------2">Continue reading on iOS App Development »</a></p></div>]]></description>
            <link>https://medium.com/ios-os-x-development/building-testable-swiftdata-applications-48af6ef2030d?source=rss-2300266301b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/48af6ef2030d</guid>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[software-testing]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[Mohammad Azam]]></dc:creator>
            <pubDate>Thu, 13 Aug 2026 19:37:48 GMT</pubDate>
            <atom:updated>2026-08-13T19:40:25.493Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Syncing SwiftData with a Custom Backend Using HistoryObserver]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://azamsharp.medium.com/syncing-swiftdata-with-a-custom-backend-using-historyobserver-87f43feca602?source=rss-2300266301b3------2"><img src="https://cdn-images-1.medium.com/max/1672/1*D4c84d_JqrxXgUnBadFAyw.png" width="1672"></a></p><p class="medium-feed-snippet">Many applications need to store data locally while also keeping a copy on a backend server. This is common in business applications where&#x2026;</p><p class="medium-feed-link"><a href="https://azamsharp.medium.com/syncing-swiftdata-with-a-custom-backend-using-historyobserver-87f43feca602?source=rss-2300266301b3------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://azamsharp.medium.com/syncing-swiftdata-with-a-custom-backend-using-historyobserver-87f43feca602?source=rss-2300266301b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/87f43feca602</guid>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[swift-programming]]></category>
            <category><![CDATA[swiftdata]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[ios-development]]></category>
            <dc:creator><![CDATA[Mohammad Azam]]></dc:creator>
            <pubDate>Fri, 17 Jul 2026 15:32:46 GMT</pubDate>
            <atom:updated>2026-07-17T15:32:46.348Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Where Should Loading State Live in SwiftUI?]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://azamsharp.medium.com/where-should-loading-state-live-in-swiftui-81751f78ecf9?source=rss-2300266301b3------2"><img src="https://cdn-images-1.medium.com/max/1672/1*UG4BxFe8fiSZgAYmG8auWw.png" width="1672"></a></p><p class="medium-feed-snippet">Handling loading states is something every SwiftUI application has to deal with.</p><p class="medium-feed-link"><a href="https://azamsharp.medium.com/where-should-loading-state-live-in-swiftui-81751f78ecf9?source=rss-2300266301b3------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://azamsharp.medium.com/where-should-loading-state-live-in-swiftui-81751f78ecf9?source=rss-2300266301b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/81751f78ecf9</guid>
            <category><![CDATA[programming-languages]]></category>
            <category><![CDATA[swift-programming]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[ios-development]]></category>
            <dc:creator><![CDATA[Mohammad Azam]]></dc:creator>
            <pubDate>Wed, 01 Jul 2026 00:38:50 GMT</pubDate>
            <atom:updated>2026-07-01T00:38:50.232Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[What’s New in SwiftData for iOS 27]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://azamsharp.medium.com/whats-new-in-swiftdata-for-ios-27-8afbd045f968?source=rss-2300266301b3------2"><img src="https://cdn-images-1.medium.com/max/1672/1*IbJfmkY7vX-lj3IFV4m1Wg.png" width="1672"></a></p><p class="medium-feed-snippet">WWDC is always an exciting time for Swift developers. Every year Apple introduces new APIs, refines existing frameworks, and occasionally&#x2026;</p><p class="medium-feed-link"><a href="https://azamsharp.medium.com/whats-new-in-swiftdata-for-ios-27-8afbd045f968?source=rss-2300266301b3------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://azamsharp.medium.com/whats-new-in-swiftdata-for-ios-27-8afbd045f968?source=rss-2300266301b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/8afbd045f968</guid>
            <category><![CDATA[swift-programming]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[swiftdata]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <dc:creator><![CDATA[Mohammad Azam]]></dc:creator>
            <pubDate>Fri, 26 Jun 2026 05:40:45 GMT</pubDate>
            <atom:updated>2026-06-26T05:40:45.041Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Announcing My New Book: SwiftData Architecture]]></title>
            <link>https://azamsharp.medium.com/announcing-my-new-book-swiftdata-architecture-f8ad65faaea6?source=rss-2300266301b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/f8ad65faaea6</guid>
            <category><![CDATA[swiftdata]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[core-data]]></category>
            <category><![CDATA[ios-development]]></category>
            <dc:creator><![CDATA[Mohammad Azam]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 15:22:10 GMT</pubDate>
            <atom:updated>2026-06-16T15:22:10.066Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9wN6YVMeLqIni26RZo9XwA.png" /></figure><p>After many months of writing, researching, testing, and revising, I am excited to announce the release of my new book:</p><p><a href="https://azamsharp.school/swiftdata-architecture.html"><strong>SwiftData Architecture — Patterns and Practices for Building Scalable Applications</strong></a></p><p>SwiftData has quickly become the preferred persistence framework for many Apple developers. It provides a modern API, deep SwiftUI integration, and significantly reduces the amount of boilerplate code required to build data-driven applications.</p><p>The demos look great.</p><p>The sample applications work perfectly.</p><p>Then real-world development begins.</p><h3>Why I Wrote This Book</h3><p>Most SwiftData tutorials focus on getting started.</p><p>Create a model.</p><p>Create a query.</p><p>Save some data.</p><p>Everything works.</p><p>But once your application starts growing, new challenges emerge:</p><ul><li>How should you structure your application?</li><li>How do you test SwiftData applications?</li><li>How do dynamic queries work?</li><li>When should you use external storage?</li><li>How do you debug SwiftData problems?</li><li>What happens when CloudKit synchronization enters the picture?</li><li>How do you handle large datasets efficiently</li><li>Can you build your own custom data store?</li></ul><p>These are the questions I encountered while building real applications and experimenting extensively with SwiftData.</p><p>This book is my attempt to answer those questions.</p><h3>What’s Inside</h3><p>The book covers a wide range of SwiftData topics, including:</p><h3>SwiftData Architecture</h3><p>Learn practical approaches for organizing SwiftData applications without introducing unnecessary complexity.</p><h3>Debugging SwiftData</h3><p>Discover techniques for inspecting your data store, understanding generated schemas, and troubleshooting common issues.</p><h3>Dynamic Queries</h3><p>Learn how to build applications that support searching, filtering, and sorting while working within SwiftData’s query system.</p><h3>CloudKit Synchronization</h3><p>Explore common CloudKit challenges and practical solutions for building synchronized applications.</p><h3>Performance Optimization</h3><p>Learn techniques for handling large datasets using fetch limits, pagination strategies, external storage, and background operations.</p><h3>Custom Data Stores</h3><p>One of my favorite chapters covers building a custom SwiftData data store from scratch. This helps developers understand how SwiftData works under the hood while opening possibilities for alternative storage implementations.</p><h3>New SwiftData Features</h3><p>The book also covers many of the latest SwiftData capabilities, including:</p><ul><li>Sectioned Queries</li><li>ResultsObserver</li><li>HistoryObserver</li><li>Codable Attributes</li><li>Compound Predicates</li><li>Improved Preview Support</li></ul><h3>Who Is This Book For?</h3><p>This book is designed for developers who have already used SwiftData and want to move beyond the basics.</p><p>If you have built a few SwiftData applications and started asking questions like:</p><blockquote><em>“How do I structure this for production?”</em></blockquote><p>or</p><blockquote><em>“What happens when this app grows?”</em></blockquote><p>then this book was written for you.</p><h3>A Practical Book</h3><p>My goal was not to create a reference manual.</p><p>Apple’s documentation already does an excellent job of explaining APIs.</p><p>Instead, I wanted to focus on practical techniques, lessons learned, tradeoffs, and real-world scenarios that developers encounter while building applications.</p><p>Many examples in the book are inspired by actual problems I have encountered while teaching, consulting, and building applications.</p><h3>Thank You</h3><p>Writing a technical book is a much larger undertaking than most people realize.</p><p>It involves researching APIs, building sample applications, testing code across multiple releases, revising chapters, and constantly updating content as the framework evolves.</p><p>I am grateful to everyone who provided feedback, reviewed early drafts, reported issues, and encouraged me throughout the process.</p><p>I hope this book helps developers build better SwiftData applications and avoid some of the mistakes I made along the way.</p><h3>Learn More</h3><p>You can learn more about the book here:</p><p><a href="https://azamsharp.school/swiftdata-architecture.html">https://azamsharp.school/swiftdata-architecture.html</a></p><p>I am excited to see what you build with SwiftData.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f8ad65faaea6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Tracking App Store Purchases with Server Notifications]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://azamsharp.medium.com/storekit-2-handles-purchases-this-handles-everything-else-4a659094b7fb?source=rss-2300266301b3------2"><img src="https://cdn-images-1.medium.com/max/1672/1*4JqJ38okuRfdDE0sYFHEXQ.png" width="1672"></a></p><p class="medium-feed-snippet">Last year I released several apps to the App Store and all of them used In-App Purchases.</p><p class="medium-feed-link"><a href="https://azamsharp.medium.com/storekit-2-handles-purchases-this-handles-everything-else-4a659094b7fb?source=rss-2300266301b3------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://azamsharp.medium.com/storekit-2-handles-purchases-this-handles-everything-else-4a659094b7fb?source=rss-2300266301b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/4a659094b7fb</guid>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[swift-programming]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[in-app-purchase]]></category>
            <dc:creator><![CDATA[Mohammad Azam]]></dc:creator>
            <pubDate>Sat, 16 May 2026 19:25:12 GMT</pubDate>
            <atom:updated>2026-05-16T22:56:58.659Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Developers Who Knew Nothing]]></title>
            <link>https://azamsharp.medium.com/developers-who-knew-nothing-a66e8493f9aa?source=rss-2300266301b3------2</link>
            <guid isPermaLink="false">https://medium.com/p/a66e8493f9aa</guid>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[vibe-coding]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Mohammad Azam]]></dc:creator>
            <pubDate>Fri, 08 May 2026 14:57:20 GMT</pubDate>
            <atom:updated>2026-05-08T14:57:20.957Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cIUXUjt1TfvrrE3QwEqmWg.png" /><figcaption>Developers Who Knew Nothing</figcaption></figure><p>Last year, I released five different apps on the App Store. Four of them were vibe coded, meaning I wrote very little code myself and let AI generate most of the implementation.</p><p>The apps look good. They work. They even make a small amount of revenue.</p><p>But if you ask me detailed questions about the codebase, I honestly would not be able to answer them confidently. The main reason is simple. I did not write most of the code. I only verified that the final result behaved the way I expected.</p><p>For small micro apps, this honestly feels fine. My apps do one thing, do it reasonably well, and stay relatively simple.</p><p>But what happens when this approach scales to large applications?</p><p>Every single day I hear the same thing from developers:</p><p>“We have not written a single line of code in months.” “Coding is dead.” “No one writes code anymore.”</p><p>Some developers even take pride in saying they no longer review the generated code. And honestly, I understand why. How do you realistically review thousands of lines of AI generated code every single day?</p><p>That is the part that scares me.</p><p>We are slowly moving toward a world where developers no longer truly understand their own codebases. In many cases, they do not even understand the domain they are building for. Requirements go into an AI tool on one side, and a working application comes out on the other.</p><p>Everything becomes optimized for speed.</p><p>But nobody is thinking deeply about what happens six months later when the system becomes harder to maintain, harder to debug, and harder to trust.</p><p>And where does responsibility fit into all of this?</p><p>Are developers still willing to stand behind the code that ships to production? Are we sure that feature actually needed 10,000 lines of generated code? Maybe the same thing could have been implemented with one tenth of the code and much better clarity.</p><blockquote><em>Programming is not like learning how to ride a bike. It is not a skill you learn once and keep forever. Programming requires constant practice. If you stop thinking deeply about architecture, debugging, problem solving, and code design, those skills slowly fade away.</em></blockquote><p>And no, this is not an anti AI post.</p><p>I use AI every single day. It has become part of my workflow. But I still use it like an instructor, not like a replacement for thinking. I want to understand what is happening underneath the surface.</p><p>AI can absolutely make us faster.</p><p>But faster without understanding is a dangerous combination.</p><p>We are definitely living in strange times.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a66e8493f9aa" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>