iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
Mobile Development

Swift iOS UIKit 初學者系列:從零開始開發互動式應用系列 第 15

【Day 15】Swift Delegate 和 Protocol -2:群組通訊案例解析

  • 分享至 

  • xImage
  •  

導言

在上一篇中,我們討論了如何使用 Delegate 和 Protocol 實現單人通訊的例子,當守衛發出「領包裹通知」時,需要事先指定好代理人,才能將通知傳送給正確的住戶。這次,我們將擴展這個概念,介紹如何處理更複雜的「群組通訊」情境。

想像一下,守衛不需要知道具體哪位住戶,而是只需告訴系統某一門牌號碼有包裹到達,系統便能自動通知所有登記在這個門牌號碼下的住戶。這將使應用程式的通訊更靈活且方便,適合多對多的通信場景。

學習目標

  • 瞭解群組通訊的實作邏輯:透過使用 Delegate 和 Protocol 來實現群組通訊,能夠掌握多對多通訊場景的解決方案。
  • 熟悉 Protocol 的擴展應用:學會如何透過 Protocol 的參數來傳遞額外的資訊,如門牌號碼,從而靈活處理不同的情境。
  • 強化程式設計的靈活性和可維護性:藉由 Delegate 機制來降低物件之間的耦合度,使應用程式更具可擴展性與可維護性。
  • 應用實例深化理解:通過生活中領包裹的場景,強化對 Delegate 和 Protocol 機制的理解,便於記憶和應用於實際開發中。

群組通訊實作


在這個更複雜但實用的例子中,我們將探討如何設計「群組通訊」。當保全只告知某一門牌有包裹到達時,所有住在該門牌的住戶都會收到通知。這樣的設計不僅簡化了通訊過程,也使得代理模式更符合多住戶的場景。

Step 1: 更新 Protocol
首先,我們在 protocol 的 "領包裹通知" 方法中加入一個參數來表示門牌號碼,讓系統根據門牌號來發送通知:

protocol 智生活APP: AnyObject {
    func 領包裹通知(forDoorNumber doorNumber: String)
}

Step 2: 守衛改用陣列存儲住戶
接著,我們將守衛的代理人從單個住戶改成一個陣列,這樣便可以同時通知多個住戶:

var 登記的住戶: [智生活APP] = []
func 登記住戶(resident: 智生活APP) {
    登記的住戶.append(resident)
}

Step 3: 群發通知
當有包裹到達時,守衛會依據門牌號通知所有住戶,並且住戶會根據門牌號來判斷是否是他們的包裹:

func 領包裹通知(forDoorNumber doorNumber: String) {
    print("保全人員通知居民包裹已送達,門牌號碼:\(doorNumber)。")
    for resident in 登記的住戶 {
        resident.領包裹通知(forDoorNumber: doorNumber)
    }
}

Step 4: 住戶處理通知
住戶收到通知後,會判斷包裹是否屬於自己家。如果是,則會準備領取包裹:

func 領包裹通知(forDoorNumber doorNumber: String) {
    if self.doorNumber == doorNumber {
        print("\(name)(門牌號碼:\(doorNumber))收到包裹通知,準備磁扣到櫃檯領包裹. 📦")
    }
}

完整程式碼
以下是完整的實作範例,展示了如何使用 Delegate 和 Protocol 來實現群組通訊的邏輯:

protocol 智生活APP: AnyObject {
    func 領包裹通知(forDoorNumber doorNumber: String)
}

class 住戶: 智生活APP {
    let name: String
    let doorNumber: String

    init(name: String, doorNumber: String) {
        self.name = name
        self.doorNumber = doorNumber
    }

    func 領包裹通知(forDoorNumber doorNumber: String) {
        if self.doorNumber == doorNumber {
            print("\(name)(門牌號碼:\(doorNumber))收到包裹通知,準備磁扣到櫃檯領包裹. 📦")
        }
    }
}

class 守衛 {
    var 登記的住戶: [智生活APP] = []

    func 登記住戶(resident: 智生活APP) {
        登記的住戶.append(resident)
    }

    func 領包裹通知(forDoorNumber doorNumber: String) {
        print("保全人員通知居民包裹已送達,門牌號碼:\(doorNumber)。")
        for resident in 登記的住戶 {
            resident.領包裹通知(forDoorNumber: doorNumber)
        }
    }
}

// 使用示例
let securityGuard = 守衛()
let resident1 = 住戶(name: "Alice", doorNumber: "A101")
let resident2 = 住戶(name: "Jason", doorNumber: "A101")
let resident3 = 住戶(name: "Jenny", doorNumber: "A101")
let resident4 = 住戶(name: "Bob", doorNumber: "A102")

securityGuard.登記住戶(resident: resident1)
securityGuard.登記住戶(resident: resident2)
securityGuard.登記住戶(resident: resident3)
securityGuard.登記住戶(resident: resident4)

securityGuard.領包裹通知(forDoorNumber: "A101")
securityGuard.領包裹通知(forDoorNumber: "A103") // 沒有對應的住戶,不會有任何通知

回顧重點

這個範例展示了如何透過 Delegate 和 Protocol 來處理群組通訊的場景,應用範圍包括但不限於群體通知、協同作業等。這樣的架構不僅使通信更靈活,也避免了對具體實現的過度依賴,從而提升了程式的可維護性。

結論

透過這個群組通訊的例子,我們可以看出 Delegate 和 Protocol 如何在物件之間實現更靈活的交互,而無需強耦合。這樣的設計既簡化了程式邏輯,又提升了可擴展性。下一篇我們將繼續探討如何處理多個 Protocol 的情況,並介紹一個以動物為主題的實例。

附錄:已接觸的 UIKit 元件

  • Protocol 和 Delegate(Day 14, 15) – 物件之間的通信機制,實現低耦合的資料傳遞與回應操作。Day 15 中介紹了如何使用 Delegate 和 Protocol 處理群組通訊的場景。
  • UITableViewDataSource(Day 14) – 表格視圖的資料來源協議,定義表格的資料呈現方式。
  • UITableViewDelegate(Day 14) – 表格視圖的委派協議,表格中的行選擇、編輯等互動。
  • UITextFieldDelegate(Day 14) – 文字輸入框的委派協議,處理輸入框的編輯行為。
  • 陣列中的 Delegate 機制(Day 15) – 使用陣列存儲多個 Delegate,實現群組通訊的情境,並使用 Protocol 傳遞額外的資料(如門牌號碼),來達到多對多的通訊模式。

上一篇
【Day 14】Swift Delegate 和 Protocol -1:領包裹案例 - 單人通訊解析
下一篇
【Day 16】Swift Delegate 和 Protocol -3:多協議應用與動物分類範例
系列文
Swift iOS UIKit 初學者系列:從零開始開發互動式應用27
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言