昨天我們將開發者的「心法」與「工具箱」都準備妥當。今天,我們終於建立我們的第一個 Xcode 專案。
第一步:打開Xcode新建專案
第二步:選擇App → 按右下角的Next
第三步:
第四步:會看到下面的畫面,代表專案已經建置好了
當建立好專案後,第一步就是試圖理解左邊那些檔案的用途。
困惑點:AppDelegate 和 SceneDelegate 這兩個檔案名字很像,它們是什麼關係?還有 Assets、LaunchScreen、Info.plist 這些,各自的功能又是什麼?
AI 協作
我剛建立了一個新的 iOS App 專案。請像一位資深工程師帶新人一樣,為我簡單介紹 AppDelegate, SceneDelegate, ViewController, Assets.xcassets, launchScreen.storyboard, 和 Info.plist這些檔案的核心功能。
AI 的回答
好的,歡迎加入 iOS 開發的行列!把這些基礎檔案搞懂,是成為一位稱職 iOS 工程師的第一步。我們把它想像成一家新創公司,而你就是創辦人,我來帶你認識一下公司的核心部門與文件。
這是在 Xcode 建立新專案後,你會在左側檔案導覽器看到的最核心的幾個檔案:
1.
AppDelegate.swift
核心功能:應用程式生命週期管理中心 (Process-Level Events)
把它想像成公司的「執行長 (CEO)」。
AppDelegate
負責處理整個 App「進程 (Process)」層級的事件。無論你的 App 有多少個畫面或視窗,整個 App 從啟動到被終止,都由它來管理。主要職責:
- 應用程式啟動與終止: 處理 App 剛啟動完成 (
didFinishLaunchingWithOptions
) 和即將被終止 (applicationWillTerminate
) 時需要執行的任務。例如:初始化第三方服務 (Firebase, Google Analytics)、設定日誌系統等。- 處理外部事件: 推播通知 (Push Notifications) 的註冊與接收、處理從其他 App 開啟的 URL (Deep Linking)。
- 核心資料的設定: 在過去 (iOS 12 及更早),它也負責設定 UI,但現在這部分職責大多已移交給
SceneDelegate
。你會在什麼時候修改它?
當你需要「在 App 一啟動時」就設定好的全域服務時,例如串接推播通知、全域的資料庫初始化。
2.
SceneDelegate.swift
核心功能:使用者介面場景生命週期管理 (UI-Level Events)
如果
AppDelegate
是 CEO,那SceneDelegate
就是特定業務線的「部門主管」。從 iOS 13 開始,為了支援 iPadOS 的多視窗功能,Apple 將 UI 生命週期的管理從AppDelegate
中獨立出來。一個Scene
代表 App 的一個 UI 實例(一個視窗)。主要職責:
- 場景的連接與斷開: 當一個新的 UI 場景(視窗)要顯示在螢幕上時 (
scene(_:willConnectTo:options:)
),SceneDelegate
會負責建立這個視窗 (UIWindow) 並設定它的初始畫面 (ViewController
)。- 場景狀態轉換: 管理場景進入前景 (
sceneWillEnterForeground
)、變為活躍狀態 (sceneDidBecomeActive
)、進入背景 (sceneDidEnterBackground
) 等。- 多視窗管理: 在 iPad 上,每個 App 視窗都有自己對應的
SceneDelegate
實例。你會在什麼時候修改它?
當 App 從背景切回前景時,你需要更新畫面資料;或是當 App 進入背景時,你需要儲存使用者的進度或暫停遊戲。這些都寫在這裡。
3.
ViewController.swift
核心功能:單一畫面的管理者
這就是你公司的「專案經理」或「第一線員工」。
ViewController
負責管理 App 中的一個特定畫面(或稱為 View)。它是 MVC (Model-View-Controller) 設計模式中的 C。主要職責:
- 管理 View 的生命週期: 從畫面被載入記憶體 (
viewDidLoad
)、即將顯示 (viewWillAppear
)、到最後從螢幕上消失 (viewDidDisappear
),都有對應的函式可以讓你掛載邏輯。- 處理使用者互動: 監聽按鈕點擊 (
@IBAction
)、處理手勢、更新畫面上的標籤 (UILabel
) 或圖片 (UIImageView
)。- 連接資料與畫面: 從 Model 層取得資料,然後將資料呈現在 View 上。
你會在什麼時候修改它?
這將是你最常、最主要撰寫程式碼的地方。App 的所有功能、畫面邏輯、使用者互動,絕大部分都在這裡實現。
4.
Assets.xcassets
核心功能:資源素材庫
這是公司的「總務部」或「素材倉庫」。所有 App 需要用到的靜態資源,都應該放在這裡統一管理。
主要職責:
- 圖片管理 (Images): 你可以把同一張圖的不同解析度版本 (例如 @1x, @2x, @3x) 放在同一個 Image Set 裡,系統會根據裝置的螢幕密度自動選用最適合的版本。
- 顏色管理 (Colors): 你可以定義全域使用的顏色,並為它命名(例如 "PrimaryTextColor")。這樣在程式碼或 Storyboard 中就可以用名稱來取用,方便統一修改與管理。
- App 圖示 (AppIcon): App 在主畫面上顯示的圖示就是在這裡設定的。
你會在什麼時候修改它?
當你需要為 App 新增一張圖片、一個圖示,或是一個客製化的顏色時,就來這裡操作。
5.
LaunchScreen.storyboard
核心功能:App 啟動過渡畫面
這是公司的「接待大廳」或「迎賓門面」。當使用者點擊 App 圖示後,在你的 App 完全準備好、第一個
ViewController
顯示出來之前,系統會先顯示這個LaunchScreen
。主要職責:
- 提供快速的視覺回饋: 讓使用者知道 App 已經開始啟動了。
- 品牌展示: 通常會放上 App 的 Logo 和一個簡單的背景色。
- 注意: 這個畫面不能執行任何程式碼,它必須是靜態的、輕量的。它的目的是盡快顯示,而不是做複雜的動畫或載入資料。
你會在什麼時候修改它?
通常你只會設定一次,把 Logo 和背景放好後,就很少再動它了。
6.
Info.plist
核心功能:App 的設定檔 (Property List)
這是公司的「工商登記證」。它是一個 XML 格式的檔案,用來儲存 App 的核心設定與元數據 (Metadata),作業系統會讀取這些資訊來了解你的 App。
主要職責:
- App 身份識別:
Bundle Identifier
:App 在 App Store 上的唯一 ID。Bundle Name
:顯示在主畫面上的 App 名稱。Bundle Version
:版本號。- 權限請求說明: 當 App 需要使用相機、定位、聯絡人等敏感權限時,你必須在這裡提供一段文字,向使用者解釋你為什麼需要這個權限。例如
Privacy - Camera Usage Description
。- 硬體與軟體需求: 設定 App 支援的裝置方向(直向、橫向)、支援的最低 iOS 版本等。
你會在什麼時候修改它?
當你要發布新版本、需要請求新的系統權限、或調整 App 的基本行為時,就需要編輯這個檔案。
大局觀:App 啟動時發生了什麼?
簡單來說,流程是這樣的:
- 使用者點擊你的 App 圖示。
- 作業系統立刻載入
LaunchScreen.storyboard
並顯示它。- 同時,系統在背景建立 App 進程,並呼叫
AppDelegate
,告訴它「你被啟動了」。AppDelegate
接著要求SceneDelegate
建立一個 UI 場景。SceneDelegate
建立一個UIWindow
,並實例化你的初始ViewController
,將其設為window
的根視圖控制器。- 當你的
ViewController
準備就緒後,系統會用它換掉LaunchScreen
,使用者就看到了 App 的主畫面。給新人的建議
一開始,你 90% 的時間都會花在
ViewController.swift
和Main.storyboard
(或 SwiftUI View) 上。先專注於如何在這上面建立畫面和處理使用者互動。當你需要圖片時,就去Assets.xcassets
;當你需要請求權限或改 App 名稱時,才去碰Info.plist
。隨著你開發的功能越來越複雜,例如需要處理推播通知或背景任務時,你自然就會回頭來找
AppDelegate
和SceneDelegate
。
SceneDelegate
的職責是「設定初始畫面」後,那能不能完全不要 Storyboard,直接用程式碼告訴 SceneDelegate
要用哪個畫面當起點?我的改造步驟:
第一步:刪除 Storyboard 在專案設定中的關聯 ,找到info 裡面的storyborad Name,點選後,直接刪掉
第二步:移除 Build Settings 中的 Main Storyboard 設定,把UIkit Main Storyborad File Base Name點選後,按下delete,注意按下刪除後還是會保留這行。
第三步:刪除專案檔案 (Main.storyboard
,LanuchScreen.storyboard
, ViewController.swift
)
第四步:建立我們自己的 MainViewController
(勾選 XIB)
第五步:修改 SceneDelegate
把我選取起的範圍用下面的程式碼取代
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// 1. 確保場景是 UIWindowScene 的實例,否則返回。
guard let windowScene = (scene as? UIWindowScene) else { return }
// 2. 創建主視圖控制器的實例,使用 XIB 檔案來初始化它。
let rootVC = MainViewController(nibName: "MainViewController", bundle: nil)
// 3. 使用主視圖控制器創建一個導航控制器。
let navigationController = UINavigationController(rootViewController: rootVC)
// 4. 創建並設置 UIWindow 的實例,這個窗口是應用的主要顯示區域。
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
// 5. 設置窗口的場景,這樣窗口就會和指定的場景關聯。
window?.windowScene = windowScene
// 6. 設置窗口的根視圖控制器為導航控制器,這樣應用的初始視圖會顯示在這個導航控制器中。
window?.rootViewController = navigationController
// 7. 使窗口顯示並成為應用的主要窗口。
window?.makeKeyAndVisible()
}
取代完後再選取一次按右鍵,選擇Create code Snippet
可以取名為defaultSceneDelegate,這樣之後就不用一直在複製貼上了
第六步:修改MainViewController
把我選取起的範圍用下面的程式碼取代
class MainViewController: UIViewController {
// MARK: - IBOutlet
// MARK: - Property
// MARK: - LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewIsAppearing(_ animated: Bool) {
super.viewIsAppearing(animated)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
}
// MARK: - UI Setting
// MARK: - IBAcion
// MARK: - Function
}
// MARK: - Extensions
取代完後再選取一次按右鍵,選擇Create code Snippet
可以取名為defaultController,這樣之後就不用一直在複製貼上了
第七步:驗證我們的 App 第一次呼吸
我打開我們剛剛建立的 MainViewController.swift
,在viewDidLoad函式裡面加入print(”Hello World!”)
override func viewDidLoad() {
super.viewDidLoad()
print("Hello World!")
}
按下 Cmd + R
執行 App,會看到右下角的控制台出現Hello World!
今天我們了解了App 的內部結構,並親手完成了專案的改造。
明天,我們就要學習如何用程式碼,在我們的App上做一些事情。