1. Protocols 定义实现协议,面向协议编码
1.1 创建面向协议实例 ProtocolsBootcamp.swift
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
protocol ButtonTextProtocol{
var buttonText: String { get }
protocol ButtonPressedProtocol{
protocol ButtonDataSourceProtocol: ButtonTextProtocol, ButtonPressedProtocol{
class DefaultDataSource: ButtonDataSourceProtocol{
var buttonText: String = "Protocols are awesome!"
print("Button was pressed!")
class AlternativeDataSource: ButtonTextProtocol{
var buttonText: String = "Protocols are lame."
struct ProtocolsBootcamp: View {
let colorTheme: ColorThemeProtocol
let dataSource: ButtonDataSourceProtocol
Text(dataSource.buttonText)
.foregroundColor(colorTheme.secondary)
.background(colorTheme.primary)
dataSource.buttonPressed()
struct ProtocolsBootcamp_Previews: PreviewProvider {
static var previews: some View {
ProtocolsBootcamp(colorTheme: DefaultColorTheme(), dataSource: DefaultDataSource())

1.2 效果图:

2. DependencyInjection 依赖式注入
2.1 创建依赖式注入的实例 DependencyInjectionBootcamp.swift
struct PostsMode: Identifiable, Codable{
protocol DataServiceProtocol {
func getData() -> AnyPublisher<[PostsMode], Error>
class ProductionDataService: DataServiceProtocol{
func getData() -> AnyPublisher<[PostsMode], Error>{
URLSession.shared.dataTaskPublisher(for: url)
.decode(type: [PostsMode].self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
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> {
let dataService: DataServiceProtocol
init(dataService: DataServiceProtocol) {
self.dataService = dataService
class DependencyInjectionViewModel: ObservableObject{
@Published var dataArray: [PostsMode] = []
var cancellables = Set<AnyCancellable>()
let dataService: DataServiceProtocol
init(dataService: DataServiceProtocol) {
self.dataService = dataService
private func loadPosts(){
} 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))
ForEach(vm.dataArray) { post in
struct DependencyInjectionBootcamp_Previews: PreviewProvider {
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 效果图:
