• Protocols/面向协议编程, DependencyInjection/依赖式注入 的使用


    1. Protocols 定义实现协议,面向协议编码

      1.1 创建面向协议实例 ProtocolsBootcamp.swift

    1. import SwiftUI
    2. /// 颜色样式协议
    3. protocol ColorThemeProtocol {
    4. var primary: Color { get }
    5. var secondary: Color { get }
    6. var tertiary: Color { get }
    7. }
    8. struct DefaultColorTheme: ColorThemeProtocol {
    9. let primary: Color = .blue
    10. let secondary: Color = .white
    11. let tertiary: Color = .gray
    12. }
    13. struct AlternativeColorTheme: ColorThemeProtocol {
    14. let primary: Color = .red
    15. let secondary: Color = .white
    16. let tertiary: Color = .orange
    17. }
    18. struct AnotherColorTheme: ColorThemeProtocol{
    19. var primary: Color = .blue
    20. var secondary: Color = .red
    21. var tertiary: Color = .purple
    22. }
    23. /// 定义按钮文字协议
    24. protocol ButtonTextProtocol{
    25. var buttonText: String { get }
    26. }
    27. protocol ButtonPressedProtocol{
    28. func buttonPressed()
    29. }
    30. protocol ButtonDataSourceProtocol: ButtonTextProtocol, ButtonPressedProtocol{
    31. }
    32. class DefaultDataSource: ButtonDataSourceProtocol{
    33. var buttonText: String = "Protocols are awesome!"
    34. func buttonPressed(){
    35. print("Button was pressed!")
    36. }
    37. }
    38. class AlternativeDataSource: ButtonTextProtocol{
    39. var buttonText: String = "Protocols are lame."
    40. }
    41. /// 面向协议
    42. struct ProtocolsBootcamp: View {
    43. let colorTheme: ColorThemeProtocol
    44. let dataSource: ButtonDataSourceProtocol
    45. var body: some View {
    46. ZStack {
    47. colorTheme.tertiary
    48. .ignoresSafeArea()
    49. Text(dataSource.buttonText)
    50. .font(.headline)
    51. .foregroundColor(colorTheme.secondary)
    52. .padding()
    53. .background(colorTheme.primary)
    54. .cornerRadius(10)
    55. .onTapGesture {
    56. dataSource.buttonPressed()
    57. }
    58. }
    59. }
    60. }
    61. struct ProtocolsBootcamp_Previews: PreviewProvider {
    62. static var previews: some View {
    63. // DefaultColorTheme / AlternativeColorTheme / AnotherColorTheme
    64. ProtocolsBootcamp(colorTheme: DefaultColorTheme(), dataSource: DefaultDataSource())
    65. }
    66. }

      1.2 效果图:

    2. DependencyInjection 依赖式注入

      2.1 创建依赖式注入的实例 DependencyInjectionBootcamp.swift

    1. import SwiftUI
    2. import Combine
    3. // Problems with singletons
    4. // 1. Singleton's are GLOBAL 单例模式是全局的
    5. // 2. Can't customize the init! 不能自定义初始化
    6. // 3. Can't swap out dependencies 不能交换式依赖
    7. struct PostsMode: Identifiable, Codable{
    8. let userId: Int
    9. let id: Int
    10. let title: String
    11. let body: String
    12. }
    13. /// 定义协议 数据服务
    14. protocol DataServiceProtocol {
    15. /// 获取数据
    16. func getData() -> AnyPublisher<[PostsMode], Error>
    17. }
    18. /// 生产者数据服务
    19. class ProductionDataService: DataServiceProtocol{
    20. /// 单例 Singleton
    21. // static let instance = ProductionDataService()
    22. let url: URL
    23. init(url: URL) {
    24. self.url = url
    25. }
    26. func getData() -> AnyPublisher<[PostsMode], Error>{
    27. URLSession.shared.dataTaskPublisher(for: url)
    28. .map({$0.data})
    29. .decode(type: [PostsMode].self, decoder: JSONDecoder())
    30. .receive(on: DispatchQueue.main)
    31. .eraseToAnyPublisher()
    32. }
    33. }
    34. /// 模拟请求服务器返回数据
    35. class MockDataService: DataServiceProtocol{
    36. let testData: [PostsMode]
    37. init(data: [PostsMode]? ) {
    38. self.testData = data ?? [
    39. PostsMode(userId: 1, id: 1, title: "One", body: "One"),
    40. PostsMode(userId: 2, id: 2, title: "Two", body: "Two"),
    41. PostsMode(userId: 3, id: 3, title: "Three", body: "Three")
    42. ]
    43. }
    44. func getData() -> AnyPublisher<[PostsMode], Error> {
    45. Just(testData)
    46. .tryMap({ $0 })
    47. .eraseToAnyPublisher()
    48. }
    49. }
    50. /// 依赖试
    51. class Dependencies {
    52. let dataService: DataServiceProtocol
    53. init(dataService: DataServiceProtocol) {
    54. self.dataService = dataService
    55. }
    56. }
    57. /// ViewModel
    58. class DependencyInjectionViewModel: ObservableObject{
    59. @Published var dataArray: [PostsMode] = []
    60. var cancellables = Set<AnyCancellable>()
    61. let dataService: DataServiceProtocol
    62. init(dataService: DataServiceProtocol) {
    63. self.dataService = dataService
    64. loadPosts()
    65. }
    66. private func loadPosts(){
    67. dataService.getData()
    68. .sink { _ in
    69. } receiveValue: {[weak self] returnedPosts in
    70. self?.dataArray = returnedPosts
    71. }
    72. .store(in: &cancellables)
    73. }
    74. }
    75. /// 依赖注入
    76. struct DependencyInjectionBootcamp: View {
    77. @StateObject private var vm: DependencyInjectionViewModel
    78. init(dataService: DataServiceProtocol){
    79. _vm = StateObject(wrappedValue: DependencyInjectionViewModel(dataService: dataService))
    80. }
    81. var body: some View {
    82. ScrollView {
    83. VStack {
    84. ForEach(vm.dataArray) { post in
    85. Text(post.title)
    86. Divider()
    87. }
    88. }
    89. }
    90. }
    91. }
    92. struct DependencyInjectionBootcamp_Previews: PreviewProvider {
    93. // static let dataService = ProductionDataService(url: URL(string: "https://jsonplaceholder.typicode.com/posts")!)
    94. static let dataService = MockDataService(data: [
    95. PostsMode(userId: 12, id: 12, title: "test", body: "test"),
    96. PostsMode(userId: 123, id: 123, title: "123", body: "123")
    97. ])
    98. static var previews: some View {
    99. DependencyInjectionBootcamp(dataService: dataService)
    100. }
    101. }

      2.2 效果图:

  • 相关阅读:
    Vision Transformer学习
    2023-亲测有效-git clone失败怎么办?用代理?加git?
    Day13--搜索历史-清空搜索历史记录
    带头双向循环链表讲解-思路清晰+画图+代码实现
    华为OD机试 - 考勤信息 - 双指针(Java 2023 B卷 100分)
    python+django+mysql鲜花水果购物网站毕业设计毕设开题报告
    关于Flask高级_Session有效期设置方法
    Qt与MQTT交互通信
    文件操作详解
    原生小程序小话题——事件绑定
  • 原文地址:https://blog.csdn.net/u011193452/article/details/133857359