Xcode relies on .xcodeproj files to manage everything. Files, groups, and build settings all live there. But here’s the catch: when you make changes outside of Xcode (like in VSCode or with Cursor AI), those changes don’t automatically appear in Xcode.
Say you add a Swift file in VSCode, Xcode won’t even notice. If you’re not careful, you’ll end up with mismatched files, broken references, or messy folder structures.
Let’s fix that! Here’s how to keep your files and project in sync, step by step.
1. Setting Up Swift in Cursor AI
Swift Extensions for Cursor
Before diving in, make sure Cursor AI fully supports Swift by installing these key extensions:
Swift Extension: Adds syntax highlighting, code completion, and navigation.
SwiftLint: Keeps your code clean and enforces Swift style guidelines.
CodeLLDB: Integrates LLDB for debugging Swift code.
Steps to Install:
Install the Swift Extension for Cursor.
Add SwiftLint to help enforce consistent Swift code styling.
Install CodeLLDB for a smooth debugging experience.
SwiftLint
While not strictly necessary, this tool helps enforce Swift style and conventions.
brew install swiftlint
Install the SwiftLint VS Code Extension.
CodeLLDB
This extension is for debugging Swift code. It integrates with LLDB to provide a rich debugging experience.
Install CodeLLDB.
Adding .cursorrules for Custom Instructions
With a .cursorrules
file, you can give Cursor specific instructions to improve your coding workflow.
Create a file named
.cursorrules
in the root directory of your project.Define how you want the AI to assist you with code, comments, or formatting.
Here’s an example of what you can add:
You are an expert in coding with Swift, SwiftUI. You always write maintainable code and clean code. Focus on the latest September 2024 versions of the documentation and features. Your descriptions should be short and concise. Don't remove any comments.
The full guide on how to create your own Cursorrules is available here.
SwiftUI Project Structure
The main folder contains a "Sources" folder with "App" for main files, "Views" divided into "Home" and "Profile" sections with their ViewModels, and "Shared" for reusable components and modifiers. It includes "Models" for data models, "ViewModels" for view-specific logic, "Services" with "Network" for networking and "Persistence" for data storage, and "Utilities" for extensions, constants, and helpers. The "Resources" folder holds "Assets" for images and colors, "Localization" for localized strings, and "Fonts" for custom fonts. Lastly, the "Tests" folder includes "UnitTests" for unit testing and "UITests" for UI testing.
SwiftUI UI Design Rules:
Use Built-In Components: Utilize SwiftUI's native UI elements like List, NavigationView, TabView, and SF Symbols for a polished, iOS-consistent look.
Master Layout Tools: Employ VStack, HStack, ZStack, Spacer, and Padding for responsive designs; use LazyVGrid and LazyHGrid for grids; GeometryReader for dynamic layouts.
Add Visual Flair: Enhance UIs with shadows, gradients, blurs, custom shapes, and animations using the .animation() modifier for smooth transitions.
Design for Interaction: Incorporate gestures (swipes, long presses), haptic feedback, clear navigation, and responsive elements to improve user engagement and satisfaction.
If you're unsure on how to work with Cursor, check out my step by step guide.
Keep Xcode and Cursor in Sync with XcodeGen
When you add or rename files in Cursor, Xcode doesn’t always get the memo. That’s where XcodeGen comes in.
XcodeGen regenerates your Xcode project to match your folder structure, so your references stay up to date and in sync.
Installing XcodeGen
If you have Homebrew, installation is easy:
brew install xcodegen
Create a Project Configuration File
XcodeGen relies on a project.yml
file to define your project’s structure and targets.
Here’s a basic example to get you going:
name: MyZunderApp
options:
bundleIdPrefix: com.zunderai
deploymentTarget:
iOS: 17.0
xcodeVersion: "15.3"
generateEmptyDirectories: true
createIntermediateGroups: true
targets:
MyZunderApp:
type: application
platform: iOS
sources: [MyZunderApp]
settings:
base:
SWIFT_VERSION: 5.10.1
ENABLE_TESTABILITY: YES
info:
path: Sources/Info.plist
properties:
CFBundleShortVersionString: "1.0.0"
CFBundleVersion: "1"
UILaunchStoryboardName: LaunchScreen
UIApplicationSceneManifest:
UIApplicationSupportsMultipleScenes: true
schemes:
MyZunderApp:
build:
targets:
MyZunderApp: all
run:
config: Debug
configs:
Debug: debug
Release: release
Make sure to replace MyZunderApp
with your project name.
Set Up Your Folder Structure
If the project.yml
is like the following:
name: MyZunderApp
Then the project directory should look like this:
mkdir MyZunderApp
Generate Your Xcode Project
xcodegen generate
Automating Tasks for a Smoother Workflow
To avoid repeating manual steps, you can automate key commands like building, syncing, or running SwiftLint.
Create a tasks.json File
Create a new file in .vscode/tasks.json
and add the following:
{
"version": "2.0.0",
"tasks": [
{
"label": "Generate Xcode Project with XcodeGen",
"type": "shell",
"command": "xcodegen",
"args": ["generate"],
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"runOptions": {
"runOn": "folderOpen"
}
},
{
"label": "Build Swift Project",
"type": "shell",
"command": "xcodebuild",
"args": [
"-project", "todoapp.xcodeproj",
"-scheme", "MyZunderApp",
"-configuration", "Debug",
"clean", "build"
],
"problemMatcher": ["$xcodebuild"],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"runOptions": {
"runOn": "default"
}
}
]
}
Have a look at my article on how you can create projects faster with advanced prompt workflow techniques.
Bonus: Use SwiftLint to Keep Code Clean
If you haven’t already, follow these steps to integrate SwiftLint:
Install SwiftLint:
brew install swiftlint
Add a SwiftLint configuration file in your project directory (
.swiftlint.yml
).Customize rules according to your needs.
Conclusion
By setting up Cursor AI with XcodeGen, SwiftLint, and automated tasks, you can keep your coding workflow smooth and consistent. Say goodbye to mismatched files and manual fixes—everything stays in sync, and you can focus on writing great code.
Check out my comparison of different AI tools you can use to help you along your journey.
Have a look at the rest of my Cursor guides:
- How to keep your code private with Cursor AI
- How to use Cursor with a large codebase
- 5 Cursor pro tips for rapid MVP development
- How to add custom documentation in Cursor AI
Happy coding!🚀