1. Protocols 定義實(shí)現(xiàn)協(xié)議,面向協(xié)議編碼
? 1.1 創(chuàng)建面向協(xié)議實(shí)例 ProtocolsBootcamp.swift
import SwiftUI
/// 顏色樣式協(xié)議
protocol ColorThemeProtocol {
var primary: Color { get }
var secondary: Color { get }
var tertiary: Color { get }
}
struct DefaultColorTheme: ColorThemeProtocol {
let primary: Color = .blue
let secondary: Color = .white
let tertiary: Color = .gray
}
struct AlternativeColorTheme: ColorThemeProtocol {
let primary: Color = .red
let secondary: Color = .white
let tertiary: Color = .orange
}
struct AnotherColorTheme: ColorThemeProtocol{
var primary: Color = .blue
var secondary: Color = .red
var tertiary: Color = .purple
}
/// 定義按鈕文字協(xié)議
protocol ButtonTextProtocol{
var buttonText: String { get }
}
protocol ButtonPressedProtocol{
func buttonPressed()
}
protocol ButtonDataSourceProtocol: ButtonTextProtocol, ButtonPressedProtocol{
}
class DefaultDataSource: ButtonDataSourceProtocol{
var buttonText: String = "Protocols are awesome!"
func buttonPressed(){
print("Button was pressed!")
}
}
class AlternativeDataSource: ButtonTextProtocol{
var buttonText: String = "Protocols are lame."
}
/// 面向協(xié)議
struct ProtocolsBootcamp: View {
let colorTheme: ColorThemeProtocol
let dataSource: ButtonDataSourceProtocol
var body: some View {
ZStack {
colorTheme.tertiary
.ignoresSafeArea()
Text(dataSource.buttonText)
.font(.headline)
.foregroundColor(colorTheme.secondary)
.padding()
.background(colorTheme.primary)
.cornerRadius(10)
.onTapGesture {
dataSource.buttonPressed()
}
}
}
}
struct ProtocolsBootcamp_Previews: PreviewProvider {
static var previews: some View {
// DefaultColorTheme / AlternativeColorTheme / AnotherColorTheme
ProtocolsBootcamp(colorTheme: DefaultColorTheme(), dataSource: DefaultDataSource())
}
}
? 1.2 效果圖:
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-724513.html
2. DependencyInjection 依賴式注入
? 2.1 創(chuàng)建依賴式注入的實(shí)例 DependencyInjectionBootcamp.swift
import SwiftUI
import Combine
// Problems with singletons
// 1. Singleton's are GLOBAL 單例模式是全局的
// 2. Can't customize the init! 不能自定義初始化
// 3. Can't swap out dependencies 不能交換式依賴
struct PostsMode: Identifiable, Codable{
let userId: Int
let id: Int
let title: String
let body: String
}
/// 定義協(xié)議 數(shù)據(jù)服務(wù)
protocol DataServiceProtocol {
/// 獲取數(shù)據(jù)
func getData() -> AnyPublisher<[PostsMode], Error>
}
/// 生產(chǎn)者數(shù)據(jù)服務(wù)
class ProductionDataService: DataServiceProtocol{
/// 單例 Singleton
// static let instance = ProductionDataService()
let url: URL
init(url: URL) {
self.url = url
}
func getData() -> AnyPublisher<[PostsMode], Error>{
URLSession.shared.dataTaskPublisher(for: url)
.map({$0.data})
.decode(type: [PostsMode].self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
/// 模擬請(qǐng)求服務(wù)器返回?cái)?shù)據(jù)
class MockDataService: DataServiceProtocol{
let testData: [PostsMode]
init(data: [PostsMode]? ) {
self.testData = data ?? [
PostsMode(userId: 1, id: 1, title: "One", body: "One"),
PostsMode(userId: 2, id: 2, title: "Two", body: "Two"),
PostsMode(userId: 3, id: 3, title: "Three", body: "Three")
]
}
func getData() -> AnyPublisher<[PostsMode], Error> {
Just(testData)
.tryMap({ $0 })
.eraseToAnyPublisher()
}
}
/// 依賴試
class Dependencies {
let dataService: DataServiceProtocol
init(dataService: DataServiceProtocol) {
self.dataService = dataService
}
}
/// ViewModel
class DependencyInjectionViewModel: ObservableObject{
@Published var dataArray: [PostsMode] = []
var cancellables = Set<AnyCancellable>()
let dataService: DataServiceProtocol
init(dataService: DataServiceProtocol) {
self.dataService = dataService
loadPosts()
}
private func loadPosts(){
dataService.getData()
.sink { _ in
} receiveValue: {[weak self] returnedPosts in
self?.dataArray = returnedPosts
}
.store(in: &cancellables)
}
}
/// 依賴注入
struct DependencyInjectionBootcamp: View {
@StateObject private var vm: DependencyInjectionViewModel
init(dataService: DataServiceProtocol){
_vm = StateObject(wrappedValue: DependencyInjectionViewModel(dataService: dataService))
}
var body: some View {
ScrollView {
VStack {
ForEach(vm.dataArray) { post in
Text(post.title)
Divider()
}
}
}
}
}
struct DependencyInjectionBootcamp_Previews: PreviewProvider {
// static let dataService = ProductionDataService(url: URL(string: "https://jsonplaceholder.typicode.com/posts")!)
static let dataService = MockDataService(data: [
PostsMode(userId: 12, id: 12, title: "test", body: "test"),
PostsMode(userId: 123, id: 123, title: "123", body: "123")
])
static var previews: some View {
DependencyInjectionBootcamp(dataService: dataService)
}
}
? 2.2 效果圖:
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-724513.html
到了這里,關(guān)于Protocols/面向協(xié)議編程, DependencyInjection/依賴式注入 的使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!