Swift
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Optionals
-
Section 4: Object-Oriented and Value Types
-
Section 5: Memory Management
-
Section 6: Generics and Error Handling
-
Section 7: Concurrency
-
Section 8: Working with Collections
-
Section 9: Codable and Data Handling
-
Section 10: Protocol-Oriented Programming
-
Section 11: Testing and Tooling
-
Section 12: Practical Projects
-
Section 13: Interview Practice
-
Section 14: More Practice Exercises
-
Section 15: More Standard Library
-
Section 16: Advanced Concurrency
-
Section 17: Foundation Framework Deep Dive
-
Section 18: URLSession and Networking Deep Dive
-
Section 19: Combine Framework
-
Section 20: SwiftUI Fundamentals for Swift Developers
-
Section 21: Server-Side Swift with Vapor
-
Section 22: Swift Package Manager Deep Dive
-
Section 23: Swift Concurrency Deep Dive
-
Section 24: More Language Features
-
Section 25: Error Handling Deep Dive
-
Section 26: Testing Deep Dive
-
Section 27: Data Structures and Algorithms in Swift
-
Section 28: More Practice Exercises
-
Section 29: More Interview Practice
-
Section 30: Swift Macros (Swift 5.9+)
-
Section 31: Property Wrappers Ecosystem
-
Section 32: Swift Interop Deep Dive
-
Section 33: iOS App Architecture Patterns
-
Section 34: Performance and Debugging
-
Section 35: App Distribution and CI/CD
-
Section 36: More Practical Projects
-
Section 37: SwiftData and Persistence
-
Section 38: More Design Patterns
-
Section 39: More Review and Practice
-
Section 40: More Foundation Deep Dive
-
Section 41: Advanced Collections in Swift
-
Section 42: Advanced Generics Practice
-
Section 43: UIKit for Legacy and Hybrid Apps
-
Section 44: watchOS and visionOS Development Basics
-
Section 45: More Networking Patterns
-
Section 46: More Testing Practice
-
Section 47: Accessibility in Swift Apps
-
Section 48: Localization
-
Section 49: More Practical Projects Round 2
-
Section 50: Swift Charts Framework
-
Section 51: More Interview and Algorithm Practice
-
Section 52: Final Practice and Mastery
-
Section 53: Swift Compiler and Build System
-
Section 54: More Concurrency Practice
-
Section 55: App Store Guidelines and Review
-
Section 56: More Design and Architecture
243: Common App Store Review Rejection Reasons
I remember the first time I submitted a production app to the App Store. I had spent three months polishing the UI and obsessing over the Swift concurrency model, thinking the hardest part was the code. I hit "Submit for Review" with a huge sense of relief, only to get a notification 24 hours later that felt like a slap in the face: Rejected.
It wasn't a bug. It wasn't a crash. It was a "Guideline 2.1 - Performance" rejection because I hadn't provided a demo account for the reviewer to actually get past the login screen. It's a rite of passage. Let's walk through a simulated submission of a "Budget Buddy" app I'm working on, and I'll show you where I usually trip up—and where you likely will too.
The Metadata Wall
I've just uploaded the build for Budget Buddy. I've got my screenshots, my description, and my keywords. I'm feeling confident. But within a day, the reviewer sends back a message saying my app is "incomplete." I look at the logs and realize I forgot to include a Privacy Policy URL.
Here's the thing: Apple doesn't care if your app is a simple local-only calculator; if you have a "Sign Up" button or request *any* permission (like the Camera or Contacts), you need a hosted URL pointing to a privacy policy. I tried to get around this by just putting "We don't collect data" in the description. That didn't work. They want a dedicated page. I ended up using a simple GitHub Pages site to host a markdown file. It's not glamorous, but it satisfies the requirement.
The StoreKit Standoff
Now that the metadata is clean, I decide to add a "Pro" tier to Budget Buddy to allow unlimited budget categories. I'm using a third-party payment processor because I like their dashboard. I submit the build, and boom—rejected again. Guideline 3.1.1.
I spent an hour arguing with myself, thinking the reviewer just didn't like my pricing. Then it clicked: I'm selling digital content (the "Pro" features) and I'm not using Apple's In-App Purchase (IAP) system. Apple is very strict here. If you are unlocking a feature inside the app, you must use StoreKit. If I were selling physical t-shirts or a gym membership, my third-party processor would be fine. But for a digital unlock? You have to give Apple their cut. I had to rip out my payment API and implement StoreKit 2. It was a pain, but it's the only way to get the "Approved" green light.
The Right to be Forgotten
I'm almost there. The IAPs are working, and the app is stable. But then I get a rejection regarding "Account Deletion." I thought, "Wait, I have a 'Logout' button, isn't that enough?"
Nope. Apple now requires that if your app allows users to create an account, it must also allow them to delete that account from within the app. I had originally just put a "Contact Support to Delete Account" link in my settings. The reviewer flagged this as an unacceptable friction point. They want a button that actually triggers the deletion process. I had to implement a backend call that wipes the user's data and removes their record from my database. It's a significant piece of work that most developers forget to plan for until the reviewer points it out.
The "Hidden" API Trap
One last hurdle. I wanted to add a fancy feature that shows the user's current battery level in the budget dashboard just for some visual flair. I found some old forum posts suggesting a specific internal framework call to get more detailed battery health data than the standard UIDevice.current.batteryLevel provides.
The app compiled perfectly. It ran great in the simulator. But Apple's automated scanners caught it immediately. They rejected the app for using a "Private API." Apple scans your binary for symbols that aren't part of the public SDK. Even if the code works, if it's not documented as public, it's a rejection. I had to strip out the custom battery logic and stick to the public API. The lesson? If you find a "secret" way to do something in Swift that isn't in the official documentation, assume it will get you rejected.
📋 Practical Task
Audit and Remediate: Budget Buddy Submission Checklist
You are acting as the QA lead for the Budget Buddy app. Based on the scenarios discussed in the lesson, examine the following "Submission Manifest" and identify the four specific reasons why this app will be rejected by the App Store Review team. For each issue, write a brief explanation of why it violates Apple's guidelines and what the specific fix should be.
SUBMISSION MANIFEST: Budget Buddy v1.0
--------------------------------------
1. Account System: Users create accounts via Firebase.
2. Account Management: "Delete Account" is handled via a support email link in the Settings menu.
3. Monetization: "Pro Version" ($4.99/mo) is processed via a Stripe integration.
4. Permissions: App requests Access to Photo Library for budget receipts; Privacy Policy is mentioned in the App Store description text.
5. Special Features: Uses a non-public 'internal_device_info' framework to detect the specific model of the user's iPhone for telemetry.
6. Reviewer Access: A username 'test_user' and password 'password123' are provided in the App Review notes.
There are no comments for now.