快速了解本篇目錄 [TOC] # Sample Code 觀摩 ## 題目 ## 1. How to achieve MVC architectural pattern? ### 1. 一般 MVC | Model( M ) | View( V ) | Controller( C ) | | -------- | -------- | -------- | | 資料(讀取、寫入、驗證)、業務邏輯 並提供給( C ) | 顯示介面,接收使用者點擊按鈕的輸入等 | 接收使用者輸入 更新( V ) | ### 2. iOS MVC | Model( M ) | View( V ) | Controller( C ) | | -------- | -------- | -------- | | 自定義結構、類、資料庫、業務邏輯、網路請求 | UILabel、UITableView等 | 處理使用者輸入、更新模型| :::spoiler  ::: :::spoiler  ::: ### 3. Sample Code MVC ```= M 放入 * Market Hot API * 自定義類 V、C 其實是綁在一起的 ``` ## 2. How to use third-party libraries? ### 1.管理方法 ```= 如何管理第三方套件 看KingFisher AlamoFire 拉出來管理第三方 將第三方套件的功能添加到原有的類別中,使代碼結構更加整潔、易於維護 根據自己的需求,在專案的其他部分使用這些功能 ```  ## 3. How to reduce duplicated code? ### 1.減少重複程式碼 ```= 不用建立兩個cell 直接在一個cell檔案,處理兩個不同cell呈現UI ```   ### 2. EX+ 減少重複程式碼 ## 4. How to handle RESTful API? ### 1. 什麼是RESTful API? 為什麼我們要使用 RESTful API ? 用一般的 API 不行嗎? 一般的 API 可能長得像這樣 ```= /api/get_file/ ( 得到檔案 ) /api/upload_file/ ( 新增檔案 ) /api/update_file/ ( 更新檔案 ) /api/delete_file/ ( 刪除檔案 ) ``` RESTful API 則長得像這樣 ```= /api/files/ ( GET -> 得到檔案 ) /api/files/ ( POST -> 新增檔案 ) /api/files/ ( PUT -> 更新檔案) /api/files/ ( DELETE -> 刪除檔案 ) ``` [參考 認識 RESTful API ](https://github.com/twtrubiks/django-rest-framework-tutorial/tree/master/RESTful-API-Tutorial) ## 5. How to pass data through closure in STTapPayViewController? ### 1. 簡單範例傳資料用closure > 點擊按鈕log印出123 :::spoiler  ::: --- >點擊按鈕傳計數器數字 :::spoiler  ::: --- >Nick分享clousre傳值到上一頁 :::spoiler  ::: ### 2. STTapPayViewController怎麼傳的 ```swift= @escaping 是一個在 Swift 中用於標註閉包(closure)的特性。 當一個閉包被標註為 @escaping 時, 表示該閉包可能在函式結束後仍然存在並被保留在記憶體中,以供其他程式碼使用。 一般情況下,當我們將一個閉包作為參數傳遞給函式時,該閉包預設是非逃逸的(non-escaping)。 這意味著閉包在函式結束之前必須被執行完畢,並且不會存儲或被其他程式碼持有。 然而,當我們希望閉包在函式結束後仍然可以被其他程式碼引用和使用時, 就需要將閉包標註為 @escaping。 這樣的閉包可以被保留在記憶體中, 並在需要的時候被呼叫,即使函式已經結束。 ``` 1. 用@escaping clousre 、 completion handler搭配來傳送資料  > 閉包就像是一個特殊的盒子,可以傳遞特定數據、指令 STTapPayViewController中,我们有一个叫做cardStatusHandler的盒子,可以傳Bool给它  > TPDForm中的表单更新时,会检查一些条件,并根据条件的结果将数据放入这个盒子中。如果条件满足,我们会把true放入盒子中;如果条件不满足,我们会把false放入盒子中。 >  ```swift= //當表單被更新時,也就是當用戶填寫或修改信用卡相關資訊時,閉包內的程式碼將會被執行。 tpdForm.onFormUpdated { [weak self] status in self?.cardStatusHandler?(status.isCanGetPrime()) } //備註 //閉包{ [weak self] status in ... } //[weak self] 是為了避免可能的內存循環問題,它告訴閉包中的程式碼要對 self 使用弱引用 //status:這是閉包接收的參數,它代表表單的狀態 /* self?.cardStatusHandler?(status.isCanGetPrime()): 這行程式碼將表單的狀態傳遞給了 cardStatusHandler 閉包。 使用 self?. 的形式表示我們只在 self 不為 nil 的情況下才呼叫 cardStatusHandler。 status.isCanGetPrime() 是一個函式, 用於檢查表單的狀態是否可獲取 prime 值。 */ ``` > 我们需要告诉这个盒子屬於誰。它屬於cardStatusHandler屬性。盒子中的數據發生變化時,STTapPayViewController就會知道。 > 方法叫做getPrime,它接受一个盒子(也就是閉包)作為参数。當我们完成一些任務並得到一个特殊的结果時,我们會將这个结果放入盒子中,並告诉盒子的所有者(也就是调用getPrime方法的地方)我们得到了什麼结果。  > 通过闭包,我们可以在STTapPayViewController中传递数据并进行一些特定的操作。闭包就像一个传输工具,帮助我们把数据从一个地方传递到另一个地方,并在需要的时候使用它们。 :::success 用圖表示 ```= 1️⃣ cardView 就像是小格子或容器,可以用來放置一張信用卡的資訊 2️⃣ cardStatusHandler 就像是傳話筒 可以接收布林值(True 或 False)的訊息。 這個傳話筒可以讓我們知道信用卡的狀態是好還是壞 3️⃣ tpdCard,它是一個特殊的卡片可以用來處理信用卡的相關操作。 它可以幫助我們檢查信用卡的資訊並獲取一個特殊的數字叫做「prime」 4️⃣ tpdForm,它就像是一個表單,可以讓我們填寫信用卡的相關資訊 例如卡號、到期月份和年份,還有安全碼。 這個表單可以讓我們檢查輸入的資訊是否正確。 4️⃣−1️⃣ tpdForm中的,onFormUpdated」,它就像是一個設定 表單被更新時應該做什麼,檢查卡片的狀態,並將這個狀態傳遞給「cardStatusHandler」 讓我們知道信用卡是可用的還是不可用的 ``` ```= (UIViewController) | | STBaseViewController | | STTapPayViewController | | ------------------------------------------- | | | | | | cardView cardStatusHandler tpdCard (IBOutlet) ((Bool) -> Void)? (TPDCard) | | tpdForm (TPDForm) | | ------------------------------------ | | | | | | | | Setup TPDForm Set Text Color Set Text Color Set Text Color (withContainer) (setErrorColor) (setOkColor) (setNormalColor) | | onFormUpdated (Closure) | | Closure Body ``` ::: | 信用卡 | 點擊結帳按鈕 | | | -------- | -------- | -------- | | | | | ## 6. What are the differences between KVO and Notification Center in implementing Trolley functionality. ### 1. 什麼是KVO KVO (Key-Value Observing) 是用來監視一個物件的屬性變化 :::spoiler  ::: ```= 想像一個小村莊裡住著一些小動物,它們之間需要互相知道彼此的狀態變化。 這時候,KVO 就像一個小偵探,它可以監視一個小動物的屬性有沒有變化。 例如,它可以監視一隻小兔子的體重有沒有增加。 一旦體重增加了,KVO 就會通知所有對這隻小兔子有興趣的人。 ``` ### 2. KVO怎麼施作購物車的函式 使用了KVO(Key-Value Observing)來觀察StorageManager類中的orders屬性的變化。 :::spoiler  ::: :::spoiler  ::: ### 3. 什麼是Notification Center Notification Center 則是用來傳遞消息給其他物件 ```= Notification Center 像是一個小廣播站,可以讓小動物之間互相傳遞消息。 這裡的消息可以是任何事情,比如說告訴大家今天天氣晴朗,或者有一個重要的活動即將開始。 當有消息需要傳遞時,小動物們可以發送通知給小廣播站, 然後廣播站會將這個消息傳給所有對這個消息感興趣的小動物。 ``` ### 4. Notification Center怎麼施作購物車的函式 ```swift= //在viewDidLoad()方法中,使用NotificationCenter註冊觀察者, //並設置通知的名稱和處理程序: override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver( self, selector: #selector(handleOrderChange), name: Notification.Name("OrderDidChangeNotification"), object: nil ) } //實現handleOrderChange方法,該方法將在收到通知時被調用, //並更新trolleyTabBarItem的badgeValue: @objc private func handleOrderChange() { if StorageManager.shared.orders.count > 0 { trolleyTabBarItem?.badgeValue = String(StorageManager.shared.orders.count) } else { trolleyTabBarItem?.badgeValue = nil } } //在StorageManager類中,當orders屬性發生變化時, //使用NotificationCenter發送通知: @objc dynamic var orders: [LSOrder] = [] { didSet { //didSet 觸發器內,程式碼發送了一個名為 "OrderDidChangeNotification" 的通知, //並將 object 參數設置為 nil NotificationCenter.default.post(name: Notification.Name("OrderDidChangeNotification"), object: nil) //通過發送這個通知,程式碼告訴其他部分或觀察者,orders 屬性的值已經發生了改變。 //這樣,其他部分可以註冊並接收這個通知,並在 orders 屬性改變時執行相應的操作 } } /* 當StorageManager的orders屬性發生變化時, 會發送一個名為"OrderDidChangeNotification"的通知, STTabBarViewController會收到這個通知並調用 handleOrderChange方法來更新UI界面中的trolleyTabBarItem 自定義的通知名稱"OrderDidChangeNotification", 可以根據需求自由命名通知名稱 NotificationCenter時不需要使用KeyPath表示法來觀察屬性變化, 而是通過發送和接收通知來實現異動的監聽 */ ``` ### KVO 與 Notification Center差異 :::danger 現在讓我們比較一下NotificationCenter與KVO之間的差異: - 使用方式不同:KVO是對特定對象的屬性進行觀察,而NotificationCenter是用於廣播和接收通知,可以由任何對象發布和接收通知。 - 觀察的對象不同:KVO是對特定對象的屬性進行觀察,而NotificationCenter是觀察通知的發布和接收。 - 通知的傳遞方式不同:KVO是直接觀察對象的屬性變化,而NotificationCenter ::: ## 7. How to establish controller for product list page? ### 1. 建立目錄頁,sample code是怎麼建立的 ```= 跟我的作法有哪裡不一樣? 型錄頁 女裝 男裝 型錄 collectionview manager ``` :::spoiler  ::: :::spoiler  ::: ## 8. Anything to be improved? Anything interesting to share? ### 1. 自己最有興趣的部分 ```= 1. 他沒有用sotryboard拉畫面,只有在cell的部分用 ``` ## SampleCode模擬器 ### 1. Detail Page 點擊加入購物車彈跳視窗 - [x] 半截頁面切換顏色尺寸數字清空 ### 2. Homa Page主頁 - [x] 百搭穿搭必敗品的資料滑到需要時才load ### 3. Checkout Page 結帳頁點擊checkout跳出畫面 - [x] TextField鍵盤沒跳出來 沒有用IQKeyBoard (嘗試加載 IQKeyboardManagerSwift.framework 的不同路徑,無法找到該檔案。最後一行指出了問題的原因:IQKeyboardManagerSwift.framework 是一個不相容的架構(有 'x86_64',需要 'arm64') - [x] 偵測到還沒登入,所以跳出1/4截登入畫面 | TextField鍵盤 | 1/4截登入畫面 | | | -------- | -------- | -------- | |  | | | ### 4. tabbar 點擊 - [x] 無論目前在哪一頁,點擊tabbard的會員都會停留在該頁,fb還沒登入都進不去 ### 5. Profile Page 個人頁面 - [x] iphone14 pro 字會壓縮到  ### 6. 購物成功 - [x] 跳出畫面  ### 7. 買完清空購物車 - [x] 跳出畫面  ###### tags: `[STYLiSH]`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up