官术网_书友最值得收藏!

There's more...

Protocol conformance can be applied to classes, structs, enums, and even other protocols, allowing an instance to be stored and passed without needing to know how it's implemented under the hood. This provides many benefits, including testing using mock objects and changing implementations without changing how and where the implementations are used.

Let's add a feature to our app that lets us set a reminder for a contact's birthday, which we will also want to save to our remote database.

We can use class inheritance to give our reminder the save functionality, but a reminder should not have the same features and functionality as a person, and our process for saving a reminder may be different to that used for a person.

Instead, we can create our Reminder object and have it conform to the Saveable protocol:

class Reminder: Saveable { 

var dateOfReminder: String // There is a better to store dates, but this suffice currently.
var reminderDetail: String // eg. Alissa's birthday

init(date: String, detail: String) {
dateOfReminder = date
reminderDetail = detail
}
var saveHandler: ((Bool) -> Void)?
var saveNeeded: Bool = true

func saveToRemoteDatabase(handler: @escaping (Bool) -> Void) {
saveHandler = handler
// Send reminder information to remove database
// Once remote save is complete, it calls saveComplete(success: Bool)
}

func saveComplete(success: Bool) {
saveHandler?(success)
}
}

Our Reminder object conforms to Saveable and implements all the requirements.

We now have two objects that represent very different things and have different functionalities, but they both implement Saveable, and therefore we can treat them in a common way.

To see this in action, let's create an object that will manage the saving of information in our app:

class SaveManager { 
func save(_ thingToSave: Saveable) {
thingToSave.saveToRemoteDatabase { success in
print("Saved! Success: \(success))")
}
}
}
let colin = createPerson("Colin", "Alfred", "Moon") // This closure was covered in the previous recipe
let birthdayReminder = Reminder(date: "27/11/1982", detail: "Colin's Birthday")
let saveManager = SaveManager()
saveManager.save(colin)
saveManager.save(birthdayReminder)

In the preceding example, our SaveManager doesn't know the underlying types that it is being passed, but it doesn't need to. It receives instances that conform to the Saveable protocol, and can, therefore, use the interface provided by Saveable to save each object.

主站蜘蛛池模板: 仁布县| 扎赉特旗| 乾安县| 西乌| 台州市| 泸溪县| 始兴县| 富源县| 康乐县| 鲁甸县| 鲁甸县| 儋州市| 淅川县| 门头沟区| 静安区| 新干县| 汤阴县| 东源县| 泰和县| 太原市| 青河县| 佛坪县| 福贡县| 镇雄县| 巩义市| 嘉荫县| 扎赉特旗| 乡城县| 达孜县| 乌拉特中旗| 时尚| 广州市| 两当县| 元谋县| 湘乡市| 杭锦后旗| 商城县| 贞丰县| 张家口市| 梅河口市| 呈贡县|