Insights & Blog
Writing on iOS development, product thinking, and what I'm learning at the Apple Developer Academy.
Feedback Is a Skill: How to Ask for It, Give It, and Actually Use It
About 60% of a designer's time, I've been told, isn't spent designing. It's spent in the messy, human, often uncomfortable territory of feedback. And yet, for something so central to the creative process, most of us were never really taught how to do it well.
Feedback isn't a formality you get at the end of a project. It's the navigation system — the thing that keeps you from drifting in the wrong direction for months, only to surface and find you've been solving the wrong problem entirely.
How to Ask a Good Question
Asking for feedback well starts before you open your mouth. It starts with understanding who you're talking to. A doctor and a designer will interpret the same question completely differently. Your job is to meet them where they are — not assume they'll meet you where you are.
Context is everything. "What do you think of this drawing?" could mean anything. But "This is an app icon for the Detroit Zoo — does it feel like it fits that world?" — now you've given them something to hold onto. Similarly, if you're showing a rough sketch, say so. Otherwise someone will critique the execution when you only needed them to respond to the concept.
Get specific. Ask about one thing at a time: the visual design, the clarity of purpose, whether the headline makes sense. Specificity is a gift to the person giving you feedback — it tells them exactly where their input will actually land.
And some things to avoid: "Do you like it?" makes honesty hard. "Do you think this is good?" is leading. "Is this better than that?" pushes people toward the answer you want rather than the one you need. Finally — really listen. Don't just wait for a pause so you can explain yourself. The reflex to defend your work the moment someone hesitates is real, and it costs you so much valuable information.
How to Give Good Feedback
When you're on the other side of the table, be curious. Ask about their project, their goals, their experience. You'll give better feedback once you understand what they're actually trying to do.
Honesty matters — but so does clarity. "It's nice" is almost useless. "It feels memorable and playful, and I think it really fits the brand's personality" — that's something a person can actually work with. Negative feedback is harder to give, but it's not an excuse to be unkind or vague. "I don't think you can design logos" is mean and useless in equal measure. "I think you're on the right track, but I'm not reading this as a hummingbird yet" is honest, specific, and actionable. The difference isn't just tact — it's information density.
How you give feedback is a significant part of how people experience working with you. And how people experience working with you is a significant part of your career.
How to Interpret Feedback
Receiving feedback is, honestly, the hardest part. The first thing to make peace with: you don't have to change something just because someone said something. Especially if that someone is senior to you. Seniority doesn't make a person right. A lot of creative work is genuinely subjective — juniors are sometimes right and seniors are sometimes wrong, and building the confidence to sit with that ambiguity is part of growing.
You also don't have to respond immediately. "I haven't considered that yet — let me think about it" is a completely valid and underrated thing to say. Then analyze what you actually heard. Is this feedback based on research? On industry knowledge? Does it reflect something 20 different people have said? Or is it one person's preference? Context shapes how much weight any given piece of feedback deserves.
Be attached to problems, not solutions. It's a muscle. It takes time. But it changes everything. And don't take it personally — when feedback is delivered unkindly, your job is to filter out the delivery and ask whether the substance still holds up. Sometimes the most valuable insight comes wrapped in the worst packaging.
A Note on Self-Reflection
Worth asking yourself, honestly: what is your instinctual reaction when someone gives you feedback? Do you go defensive? Do you shut down? Do you over-apologize? Self-awareness here isn't just navel-gazing — it's the first step to actually being able to change your patterns in real time. What are your biases? What kinds of feedback are you inclined to dismiss, and why? Knowing this doesn't eliminate the bias, but it at least gives you a fighting chance to notice it before it costs you something.
On Imposter Syndrome (Because It's Always There)
There will always be someone more talented, more accomplished, more confident-seeming than you. That feeling — the one that says you don't belong here — doesn't really go away. The goal isn't to eliminate it. It's to learn to move through it anyway. Know your strengths. Know your weaknesses. Ask "why not me?" more often than you think you're allowed to. Growth is slow and the gap between where you are and where you want to be can feel crushing — but someone who was once in your position is now the person people look up to. That trajectory is real. Keep going.
Feedback is a skill. Like any skill, it requires deliberate practice — in how you ask for it, how you give it, and how you sit with it when it's hard. The people who get good at all three tend to go somewhere.
What I Actually Learned Finishing the Claude Code in Action Certification
I finished the Claude Code in Action certification this week, and the thing that stuck with me most wasn’t any specific feature — it was a shift in how I think about what AI is actually for in a development workflow.
I came in thinking of AI tools as sophisticated autocomplete. You describe what you want, it suggests code, you decide whether to keep it. The course reframed that pretty quickly. The real unlock isn’t the code generation — it’s the agentic part. Setting up Claude to actually run terminal commands, manage files, and execute changes without you narrating every step. That’s a different relationship with the tool entirely.
The thing that changed how I work
Context management was the piece I underestimated going in. Getting the AI to understand how one part of a project affects another — not just what a single file does, but how changes ripple — is genuinely hard to set up and genuinely useful once it works. Before this course I was treating every prompt like a fresh conversation. After, I started thinking about what context the model actually needs to give me something useful, and that’s made the output noticeably better across everything I’m building.
The MCP section (Model Context Protocol) was the other one that clicked for me in a non-obvious way. It’s essentially a standard for connecting AI to live data — your actual codebase, external APIs, databases — securely and in real time. The interesting part isn’t the implementation, it’s the implication: the gap between "AI that knows about your project in theory" and "AI that can see what your project actually is right now" is larger than I thought, and MCP is what closes it.
Honest take on where this fits
I don’t think any of this replaces understanding what you’re building or why. The hooks and automation features are useful, but they’re most useful when you already have a clear mental model of your codebase — otherwise you’re just automating confusion faster. The SDK work at the end of the course was the clearest example of that: you can extend Claude’s capabilities for specific environments, but you have to know what you actually need before you can build it.
What I took away is that AI tools reward the developer who knows their domain. The better you understand what you’re trying to do, the more leverage you get. That felt worth writing down.
What an iOS Developer Actually Gets Out of the Apple Ads Certification
I built Stamped!, published it to the App Store, and then immediately ran into the part nobody talks about in app development courses: now what? You have a working product and zero users. The Apple Search Ads certification felt like the natural next step — not because I'm planning to run ad campaigns tomorrow, but because building apps without understanding how discovery works is like designing a building without knowing where the entrance is.
What I didn't expect was how much the course would change how I think about the App Store itself, before you even spend a dollar on ads.
The part that reframed everything
The biggest mental shift was understanding that the App Store is an auction, not a meritocracy. Your app showing up when someone searches "city passport app" isn't just about whether your app is good — it's about whether you've told Apple what searches you want to show up for, and whether you're bidding competitively against everyone else who wants that same user. That sounds obvious written out, but the implications go deep. Your app's metadata, screenshots, and keyword choices are all part of the same system. Ads just make it explicit.
The Max CPT concept (Maximum Cost-Per-Tap) is a good example of how the system actually works. Apple runs a second-price auction — you set the maximum you'll pay per tap, but you typically pay just enough to outbid the next competitor, not your full ceiling. So if your cap is $1.00 and the next highest bid is $0.40, you pay around $0.41. The implication: setting a reasonable bid matters more than setting a low one, because a bid that's too conservative means your ad doesn't show at all. You can actually work backwards from a target cost-per-install to figure out a rational Max CPT, which made the whole thing feel much less like guesswork.
Campaign structure and the thing I'll actually use
The recommended campaign structure — Brand, Category, Competitor, and Discovery — was one of those things that seemed overly formal until I thought about it in terms of Stamped!. Brand campaigns protect your name. Category captures people who don't know your app exists but are looking for what you do — things like "travel passport app" or "city exploration app." Discovery is where you let Apple find terms you haven't thought of yet.
The negative keyword piece is the insight I'll carry longest. You add your known high-performing keywords as negatives in Discovery, which forces Apple's algorithm to surface genuinely new terms. For Stamped!, that means adding "city passport" and "stamp collector app" as negatives so the system goes looking for things like "Detroit bucket list" or "things to do in Detroit" — exactly the right audience. It's a small structural choice that changes the quality of what you learn.
Why this matters even if you're not running ads yet
Understanding how App Store advertising works made me look at Stamped!'s metadata differently. The keywords I choose for the App Store listing, the screenshots I lead with, the subtitle I use — these aren't just aesthetic decisions, they're signals in a system that determines whether the right people ever find the app at all. That's worth knowing whether or not you're spending money on ads.
Building a Modern Python API: FastAPI, Pydantic, httpx, Uvicorn, Thunder Client, and Render
When I set out to build a robust backend for my portfolio projects, I wanted speed, clarity, and reliability. FastAPI checked all the boxes: it’s async-first, type-safe, and developer-friendly. Here’s how I shipped a production-ready API using FastAPI, Pydantic, httpx, Uvicorn, Thunder Client, and Render.
→ Related project: CoastCast Case Study- FastAPI & Pydantic: FastAPI lets you define endpoints with Python type hints, and Pydantic handles data validation and serialization. This means you get automatic docs, clear error messages, and confidence your data is always correct.
- httpx: For async HTTP requests, httpx is my go-to. It’s fast, supports async/await, and makes it easy to fetch external data (like weather or exchange rates) and integrate with other APIs.
- Uvicorn: Uvicorn is the lightning-fast ASGI server that powers FastAPI in production. It’s simple to run locally and scales well on Render.
- Thunder Client: Testing APIs shouldn’t be a chore. Thunder Client (a VS Code extension) lets me quickly test endpoints, check responses, and debug issues without leaving my editor.
- Render: For hosting, Render is a game-changer. It’s easy to deploy FastAPI apps, manage environment variables, and set up automatic builds from GitHub. Render’s free tier is perfect for prototypes, and scaling up is seamless.
Sample Endpoint:
from fastapi import FastAPI
from pydantic import BaseModel
import httpx
app = FastAPI()
class Weather(BaseModel):
city: str
temperature: float
@app.get("/weather/{city}", response_model=Weather)
async def get_weather(city: str):
async with httpx.AsyncClient() as client:
resp = await client.get(f"https://api.weatherapi.com/v1/current.json?key=YOUR_KEY&q={city}")
data = resp.json()
return Weather(city=city, temperature=data["current"]["temp_c"])
Takeaways: Combining FastAPI, Pydantic, httpx, Uvicorn, Thunder Client, and Render makes backend development fast, reliable, and fun. I can ship new endpoints in minutes, test them instantly, and deploy updates with zero downtime.
Read the CoastCast Case Study
Visiting the Water Board Building: Initiative & Real-World Impact
Sometimes, the best opportunities come from a bit of luck and a lot of initiative. On a recent visit to the Water Board Building with my Challenge 5 team, we had no idea that our trip would coincide with the monthly board meeting. We simply wanted to learn more about the organization and explore ways our skills could make a real difference in the community.
As we entered, we found ourselves in the midst of the board meeting. Rather than quietly observing, our project manager seized the moment and stood up to address the board directly. With genuine curiosity and a spirit of service, she asked if there were any pain points the board faces daily that technology—and our team—could help solve.
The board responded candidly, sharing a real challenge they encounter. This unexpected conversation may have set the stage for our Challenge 5 project and, potentially, secured a client whose needs align perfectly with our mission to create meaningful, real-world impact.
We are now waiting to meet with the board again, eager to learn more and begin working on a solution. This experience is a testament to the power of showing up, asking questions, and being ready to serve. Our journey to the Water Board Building was more than a search for a project—it was a step toward making a lasting difference in our community.
Challenge Based Learning: What It Is and Why It Matters
What is Challenge Based Learning (CBL)?
Challenge Based Learning is an educational approach where learners tackle real-world challenges through hands-on projects, teamwork, and iterative problem solving. Instead of memorizing facts, students identify a meaningful challenge, research solutions, build prototypes, and reflect on their process. CBL encourages creativity, collaboration, and practical application of knowledge.
History:
CBL was developed by Apple in 2008 as part of their education initiatives. It was designed to make learning more engaging and relevant by connecting classroom activities to real-world issues. The method has since been adopted by schools, universities, and organizations worldwide—including the Apple Developer Academy, where I experienced CBL firsthand.
How It Works:
1. Engage Phase: Start with a big question or real-world problem. This phase includes developing an Essential Question (a broad, meaningful inquiry), a Challenge Statement (the actionable challenge to solve), and Guiding Questions (specific questions that help break down the challenge and focus investigation).
2. Investigate Phase: Research, brainstorm, and explore possible solutions. Here, learners answer guiding questions, gather evidence, and refine their understanding of the challenge.
3. Act Phase: Build, test, and iterate on a solution. Teams develop prototypes, implement their ideas, and share results.
4. Reflect: Share results, learn from feedback, and improve. Reflection includes evaluating the process, outcomes, and learning gained.
- Essential Question: A broad, meaningful inquiry that frames the learning experience. Example: "How can technology improve accessibility in our city?"
- Challenge Statement: The actionable challenge to solve. Example: "Design an app that helps people with disabilities navigate public spaces in Detroit."
- Guiding Questions: Specific questions that help break down the challenge and focus investigation. Example: "What barriers do people with disabilities face? What features would make navigation easier? How can we ensure the app is inclusive?"
Examples & Places Used:
- Apple Developer Academy: Teams work on civic tech, accessibility, and product design challenges.
- Universities: Engineering and business students solve sustainability, health, and social impact problems.
- K-12 Schools: Students address local community issues, like recycling or safety.
- Corporate Training: Employees use CBL to innovate and improve workflows.
My Experience:
At the Apple Developer Academy, CBL shaped how I learn and build. Working in teams, we tackled real challenges—like improving accessibility in apps or designing civic platforms. The process taught me to collaborate, iterate, and connect learning to real impact.
Why It Matters:
CBL prepares learners for the real world. It builds critical thinking, teamwork, and adaptability. By focusing on authentic challenges, it makes learning meaningful and empowers students to make a difference.
Learn more about Challenge Based Learning at Apple Learning Center
Understanding @StateObject vs @ObservedObject in SwiftUI: A Reflective Guide
As I continue to deepen my SwiftUI knowledge, I often revisit the distinction between @StateObject and @ObservedObject. This post is both a reference for others and a personal learning log—a place to clarify, reflect, and return to when I need a refresher.
What is @StateObject?
- Ownership: Use
@StateObjectwhen your view is responsible for creating and owning the lifecycle of the observable object. - Initialization: The object is initialized once for the lifetime of the view.
- Persistence: SwiftUI keeps the object alive as long as the view exists, even if the view is recreated due to state changes.
- Typical Use: Root or parent views that create the model.
What is @ObservedObject?
- Reference: Use
@ObservedObjectwhen the observable object is created elsewhere and passed into the view. - No Ownership: The view does not own the object; it just observes it for changes.
- Re-initialization: If the parent view recreates the child, the observed object is not re-initialized (unless the parent provides a new instance).
- Typical Use: Child or subviews that receive the model from a parent.
Common Pitfalls
- Using
@ObservedObjectfor creation: If you create an object with@ObservedObjectin a view, it will be recreated every time the view reloads, losing state. - Multiple sources of truth: Accidentally creating two instances of the same model by mixing
@StateObjectand@ObservedObjectin the wrong places.
Quick Reference Table
| @StateObject | @ObservedObject | |
|---|---|---|
| Who creates? | The view itself | Parent or external |
| Who owns? | The view | Parent/external |
| When to use? | Root/parent view | Child/subview |
| Lifecycle | Persists for view's life | Follows reference |
Personal Reflection
Every time I get tripped up by a disappearing model or a view that doesn’t update, it’s usually because I mixed up @StateObject and @ObservedObject. Writing this out helps me remember: create and own with @StateObject, observe with @ObservedObject. When in doubt, check who should own the data and where it’s created.
Further Reading
Structs vs. Classes in SwiftUI: What’s the Difference?
When building apps with SwiftUI, you’ll often use both structs and classes—but understanding their differences is key to writing clean, efficient code.
Structs are value types. When you create a struct and assign it to a new variable, Swift copies the entire value. This makes structs predictable and safe for UI components. In SwiftUI, views are almost always structs because they’re lightweight and easy to manage. Structs don’t support inheritance, but they do support protocol conformance.
Classes are reference types. When you assign a class to a new variable, both variables point to the same object in memory. Classes are ideal for managing shared state, like data models or observable objects. Classes support inheritance, which lets you build more complex hierarchies. In SwiftUI, you’ll use classes for things like ObservableObject to manage app data and notify views of changes.
When to use each?
Use structs for UI, simple data, and anything that doesn’t need to be shared or mutated across multiple places.
Use classes for shared state, data models, and objects that need to be observed or mutated by multiple views.
struct CityView: View {
var cityName: String
var body: some View {
Text(cityName)
}
}
class CityData: ObservableObject {
@Published var cityName: String = "Detroit"
}
Summary: Structs keep your UI fast and safe. Classes help you manage shared, mutable data. Knowing when to use each is a core skill for any SwiftUI developer.
How to Upload a Project to the App Store
Publishing your app to the App Store is a milestone for any developer. Here’s a step-by-step guide based on my experience:
- Prepare Your App: Make sure your app is complete, tested, and follows Apple’s guidelines. Check for bugs, accessibility, and polish your UI.
- Set Up App Store Connect: Create an App Store Connect account and register your app. Fill in metadata, screenshots, and descriptions.
- Configure Xcode: Set your app’s bundle identifier, version, and build number. Make sure your provisioning profiles and certificates are correct.
- Archive and Validate: In Xcode, select Product > Archive. Once archived, validate your build to catch any issues before submission.
- Fill Out Required Information: Before submitting, you must provide:
- App Name & Subtitle: The name and a short tagline for your app.
- App Icon: High-resolution icon (1024x1024px).
- Category: Choose the main and secondary categories for your app.
- Privacy Policy URL: Link to your privacy policy.
- App Description: Detailed description of your app’s features and value.
- Keywords: Words to help users find your app.
- Support URL & Contact: Where users can get help.
- Screenshots: Upload screenshots for all supported devices (iPhone, iPad, etc.).
- Age Rating: Answer Apple’s questionnaire to determine your app’s age rating.
- Compliance Questions: Answer export compliance, content rights, and other legal questions.
- Version Release Notes: What’s new in this version.
- Submit for Review: Complete all required fields, answer compliance questions, and submit your app for Apple’s review.
- Respond to Feedback: If Apple requests changes, address them promptly and resubmit. Be patient—review times can vary.
- Release Your App: Once approved, set your release date or launch manually. Celebrate your achievement!
Tips: Read Apple’s guidelines, test on real devices, and prepare clear screenshots and descriptions. Stay positive—every step is a learning opportunity!
Apple Intelligence: On-Device Foundation Models
Apple Intelligence is Apple’s new suite of on-device AI features powered by foundation models. I’ve started experimenting with these capabilities in my projects—using the on-device foundation model in Stamped! to generate personalized itineraries for users, and in CommonSight to create dynamic story cards that help tell the story of Detroit neighborhoods. The ability to run powerful AI directly on the device is pretty amazing: it keeps user data private, enables fast responses, and opens up new creative possibilities.
Personal Story: When I first integrated Apple Intelligence into Stamped!, I was blown away by how quickly the itinerary generator adapted to user preferences. It felt like magic—seeing the app suggest routes and activities based on real input. In CommonSight, the story cards became more dynamic and engaging, helping users connect with Detroit’s neighborhoods in a new way.
Technical Details: I used Apple’s foundation model APIs to process user data locally, ensuring privacy and speed. The integration was straightforward, but tuning the model for my specific use cases took some trial and error.
Lessons Learned: On-device AI is powerful, but it’s important to balance automation with user control. I learned to provide clear options and feedback so users feel empowered.
What’s Next: I plan to experiment with more personalized recommendations and interactive features, and I’m excited to see how Apple Intelligence evolves.
User Impact: Early testers loved the privacy and speed, and their feedback helped me refine the experience.
Learn more about Apple Foundation Models
LAWS OF UX: what are they and why do they matter
The Laws of UX are foundational principles drawn from psychology and cognitive science that guide designers in creating intuitive, user-friendly interfaces. By understanding how people perceive, process, and interact with information, designers can build products that feel natural and easy to use. I genuinely enjoy design and want to learn as much of it as I can in order to be a stronger software engineer—improving communication and understanding between design and engineering teams.
Personal Story: My interest in design started when I realized how much a simple UI tweak could change the way people use an app. At the Apple Developer Academy, I saw firsthand how accessibility and clarity make a difference for real users.
Technical Details: I apply principles like Hick’s Law and Fitts’s Law in my projects, using minimal navigation and high-contrast buttons. In SlotParking, I used SwiftUI’s accessibility features to make the app usable for everyone.
Lessons Learned: Design is about empathy—understanding what users need and making their experience seamless.
What’s Next: I want to keep learning, attend more design talks, and collaborate with designers to bridge the gap between engineering and design.
User Impact: Feedback from users and mentors has helped me refine my approach and build more intuitive products.
My Favorite Laws
- Hick’s Law: The time it takes to make a decision increases with the number and complexity of choices. I use this principle to simplify navigation and reduce cognitive overload in my apps. For example, SlotParking’s UI is intentionally minimal, helping attendants and drivers make quick choices in busy environments.
- Jakob’s Law: Users spend most of their time on other sites, so they expect your site to work the same way. I leverage familiar patterns and conventions to make onboarding seamless and reduce friction. When designing Stamped!, I used recognizable navigation and feedback cues to help users feel instantly comfortable.
- Fitts’s Law: I design interfaces to minimize cognitive overload, ensuring key actions are easy to find and interact with—especially in mobile and accessibility-focused apps. Large, high-contrast buttons in SlotParking make it easy for attendants to update spot counts, even in bright sunlight or with gloves.
- Peak-End Rule: Users judge experiences largely by the peak (most intense point) and the end. I focus on creating memorable moments and positive wrap-ups in onboarding, tutorials, and app flows. In Stamped!, the celebration animation after completing a city is designed to leave a lasting impression.
- Paradox of the Active User: Users often skip instructions and dive right in. I design for immediate usability, making sure key actions are discoverable and feedback is clear—even for first-time users. SlotParking’s onboarding is just a few taps, so attendants can start using it right away.
How I Apply These Laws
Every project I build—from SlotParking to Stamped!—reflects these principles. I prioritize clarity, reduce unnecessary choices, and use familiar patterns to help users feel confident and in control. Accessibility and usability are always at the core of my design process. Hearing the creator of lawsofux.com speak live at DevCreate313 inspired me to dig deeper into these principles and apply them in real-world projects.
Personal Takeaways
Learning and applying the Laws of UX has made me a more thoughtful designer. I’ve seen firsthand how small changes—like simplifying a menu or making a button bigger—can dramatically improve user satisfaction. I recommend Laws of UX (lawsofux.com) to anyone serious about design. It’s practical, actionable, and rooted in real science.
Further Reading
- Laws of UX (lawsofux.com) — Highly recommended! I heard the creator speak live at a DevCreate313 meeting—check it out for practical, actionable design principles.
- Nielsen’s Usability Heuristics
TestFlight: Feedback & Iteration
I’ve used TestFlight to beta test Stamped!, TakeFlight, Relationship Builder, and other smaller projects. The platform makes it easy to distribute pre-release builds, gather real user feedback, and iterate quickly. I feel comfortable with both the technology and the process of receiving feedback—because feedback is a gift. It helps me build software that’s truly usable, not just what I think is right.
Personal Story: The first time I sent out a TestFlight build, I was nervous—what if people didn’t like it? But testers gave honest feedback, and I learned to embrace it. Their suggestions led to real improvements.
Technical Details: I use TestFlight’s crash reports and feedback tools to track issues and prioritize fixes. Managing testers and updates is straightforward, and I’ve built a routine for quick iterations.
Lessons Learned: Feedback is essential. It’s not always easy to hear, but it’s what makes software better.
What’s Next: I plan to expand my tester pool and try new features in future projects.
User Impact: Testers have helped shape my apps, making them more reliable and user-friendly.
Learn more about TestFlight
CommonSight: Building a Civic Platform
CommonSight is my first internship and my first experience working with a boss in tech. I’m enjoying the process—learning how to collaborate, take feedback, and build a civic platform that empowers Detroit neighborhoods. The project has taught me about real-world teamwork, technical challenges, and the importance of clear communication. It’s exciting to see our work make a difference in the community.
Personal Story: Early in the internship, I was nervous about working with a boss and a new team. But I quickly learned the value of collaboration and open communication.
Technical Details: We use Firebase and SwiftUI to build scalable features for CommonSight. Integrating AI for story cards was a new challenge, but rewarding.
Lessons Learned: Teamwork and feedback are key. Building for civic impact means listening to the community.
What’s Next: As I get deeper into the internship, I plan to write more about our progress and impact.
User Impact: Community feedback has shaped our roadmap and helped us prioritize features.
Read the CommonSight Case Study
Shipping MVPs That Matter
SlotParking is my first MVP designed for real-world impact. I am trying to incorporate all the lessons I learned in the Apple Developer Academy into this project—taking an idea and making it a product in the real world. Instead of building in isolation, I’m launching a hands-on pilot in Detroit—personally visiting parking lots, pitching the app to owners, and using flyers to drive adoption. The goal: make finding a parking spot in busy downtown Detroit easier for everyone, using tech that solves a real problem. By showing the MVP to actual users and lot owners, I’m gathering feedback, validating the product, and learning what works. This approach lets me iterate quickly and build a solution that truly meets the needs of the city. In the future, I will ask for advice on whether this could be monetized.
Personal Story: I remember the first time a lot owner gave me feedback—it was tough, but it helped me see the real needs of users. Every conversation is a chance to improve.
Technical Details: SlotParking uses SwiftUI, Firebase, and real-time updates to track parking spots. I built the MVP with a focus on usability and quick iteration.
Lessons Learned: Building for the real world means adapting fast and listening to feedback.
What’s Next: I want to explore monetization and continue testing to see if SlotParking works in Detroit.
User Impact: User feedback has shaped the app and helped me prioritize features.
Read the SlotParking Case Study
My First App on the App Store
Launching Stamped!—a city passport app on the App Store was a milestone in my developer journey. This was the first app I built that I really felt passionate about, and it showed—I would stay up late and wake up early to build it. I was obsessed. Stamped! lets users explore cities, check in at landmarks, and collect digital stamps for their travel adventures. From initial concept to shipping, I learned how to design engaging progression loops, polish UI/UX for accessibility, and navigate Apple's review process. Responding to real user feedback helped me iterate quickly and improve the experience. Seeing Stamped! live and available to travelers worldwide was both exciting and humbling—and it inspired me to keep building and improving. There are still many things I want to work on in future updates, and balancing that with work and other projects is difficult, but I want to add a live currency converter, a full translator, make it available in different languages, and possibly experiment with monetization through a pro version. This was a real milestone for me. If you're working toward your first launch, stay curious, keep learning, and celebrate every step!
Personal Story: I was obsessed with Stamped!—sometimes working late into the night, sometimes waking up early just to fix a bug or add a feature. The passion paid off when users started sharing their travel stories.
Technical Details: Stamped! uses SwiftUI, CoreData, and integrates with Apple Intelligence for itinerary generation. I focused on accessibility and user feedback throughout development.
Lessons Learned: Passion drives progress, but feedback shapes the product.
What’s Next: I want to add more features, expand to new cities, and experiment with monetization.
User Impact: User stories and feedback have inspired new features and improvements.
View Stamped! on the App Store
My Thoughts on Xcode 26.3
Xcode 26.3 feels like a mature, polished IDE for Apple developers. I began learning code at an interesting time—this is my first IDE, and I want it to help me work faster, but also explain things I may not have learned yet. I want it to help me learn and be a tool, not a crutch. The new features—especially improved SwiftUI previews, faster build times, and enhanced accessibility tools—make daily development smoother and more productive. I appreciate the stability and performance improvements, as well as the expanded support for Apple Intelligence APIs. The UI is cleaner, and the debugging experience is more intuitive. One standout is how Xcode is starting to support agentic coding: workflows where AI and automation help generate, refactor, and test code alongside the developer. This shift makes coding more collaborative and efficient, letting me focus on creative problem-solving while routine tasks are handled by smart tools.
Personal Story: Learning code with Xcode as my first IDE was a wild ride. I made plenty of mistakes, but each one taught me something new.
Technical Details: I use SwiftUI, Apple Intelligence APIs, and Xcode’s debugging tools daily. The IDE helps me work faster and learn as I go.
Lessons Learned: Tools are important, but curiosity and persistence matter more.
What’s Next: I want to keep exploring new features and push the limits of what Xcode can do.
User Impact: Feedback from teammates and mentors has helped me improve my workflow.
Learn more about Xcode
The 9:41 Rule: Steve Jobs and Apple’s Iconic Time
If you look closely at Apple’s marketing images, you’ll notice a curious detail: the time on iPhones and iPads is almost always set to 9:41. This isn’t a coincidence—it’s a tribute to a historic moment in Apple’s history.
The Origin: The 9:41 rule began with the launch of the original iPhone. During Steve Jobs’ legendary keynote on January 9, 2007, he revealed the iPhone to the world at exactly 9:41 AM. Apple’s designers set the time in all product images to match that moment, creating a subtle nod to the company’s biggest milestone.
Why 9:41? Apple’s presentations are meticulously timed. The team wanted the product reveal to coincide with the time shown on the screen. When Jobs unveiled the iPhone, the clock matched the keynote’s schedule—making 9:41 a symbol of innovation and precision.
Design Impact: Since then, 9:41 has appeared in nearly every Apple device image, from iPhones to iPads and Macs. It’s a small detail, but it reflects Apple’s attention to storytelling and brand consistency.
Fun Fact: Before the iPhone, Apple used 9:42 for the original Macintosh launch. The switch to 9:41 marked a new era for the company.
Takeaway: The 9:41 rule is more than just a time—it’s a reminder of Apple’s culture of detail, history, and the impact of Steve Jobs’ vision. Next time you see an Apple ad, check the clock!
Designing with Apple’s Human Interface Guidelines (HIG)
The Apple Human Interface Guidelines (HIG) are the gold standard for designing intuitive, accessible, and beautiful apps for iOS, macOS, and beyond. As a developer and designer, I’ve found that following the HIG not only improves usability but also helps apps feel at home on Apple platforms.
What is the HIG?
The HIG is Apple’s official design framework, covering everything from navigation and layout to color, typography, and motion. It’s a living document that evolves with each platform update, providing best practices for building apps that are clear, consistent, and delightful to use.
Why Follow the HIG?
- Consistency: Apps that follow the HIG feel familiar to users, reducing the learning curve and building trust.
- Accessibility: The HIG emphasizes readable text, sufficient contrast, and support for assistive technologies—making apps usable for everyone.
- Efficiency: By using standard components and patterns, you can build faster and avoid reinventing the wheel.
- App Store Success: Apple reviews apps for HIG compliance, so following the guidelines can help you get approved and featured.
Key Principles I Apply
- Clarity: Every element should have a clear purpose. I use whitespace, hierarchy, and concise labels to guide users.
- Deference: The interface stays out of the way, letting content and actions shine. Subtle animations and transitions help users stay oriented without distraction.
- Depth: Visual layers and motion create a sense of place, making navigation feel natural and engaging.
Lessons from My Projects
In projects like Stamped! and SlotParking, I applied HIG principles to design navigation bars, tab bars, and modals that feel native to iOS. I paid special attention to touch targets, color contrast, and dynamic type. Testing with real users helped me refine flows and catch accessibility issues early.
Tips for Applying the HIG
- Start with Apple’s templates and components in Xcode or SwiftUI.
- Use SF Symbols for icons—they scale and adapt automatically.
- Test with VoiceOver and Dynamic Type enabled.
- Stay up to date: review the HIG with each major iOS/macOS release.