如何在Swift中创建一个框架

263 阅读6分钟

框架对于模块化你的代码是很好的,将可重复使用的组件分解成独立的代码束。

例如,考虑一个提供录制屏幕功能的应用程序。我们将与录制有关的方法和类移到一个不同的框架中,并将其命名为RecordingKit。这个框架的创建考虑到了可重用性,也可以用于其他场景。同时,其他工程师也可以在其中独立工作。

在这篇文章中,我们将学习这些步骤。

  • 创建一个框架
  • 把它导入到一个项目中
  • 在一个项目中使用它

要继续学习,你应该有Swift语言的基本知识和使用Xcode的经验。

简介

随着最近股市和加密货币的热潮,我们想要一个投资追踪器的应用程序。这些将分别跟踪证券交易所的股票和一些加密货币的价格。

该应用程序需要一个设置屏幕,为了保持一致性,我们不想重复代码。因此,我们将创建一个名为SettingsKit的框架,以便在我们的应用程序中重复使用(或许将来会有更多)。

创建一个新的框架

打开Xcode并创建一个新项目。选择iOS部分下的框架

Startup Menu for Xcode

按如下方式填写模板选项,然后点击下一步

  • 产品名称。SettingsKit
  • 组织标识符。你想为你的框架使用的标识符。比如说。com.rudrankriyam.SettingsKit
  • 语言。Swift
  • 取消勾选 "包括测试"选项

Initial Framework Info for Xcode

选择一个目录来保存框架,然后点击创建

现在,创建一个新的SwiftUI视图,并将其命名为SettingsRow.swift。这是一个带有名称和图像的通用行,有一个披露指标。确保检查目标中的框架。

New SwiftUI View for Xcode

在文件内复制以下代码,SettingsRow

public struct SettingsRow: View {
  private var title: String
  private var image: String
  private var showDisclosure: Bool

  /// A generic settings row which can be customised according to your needs.
  /// - Parameters:
  ///   - title: The title of the row.
  ///   - image: The SF symbol for the row.
  ///   - showDisclosure: Show disclosure icon for action or navigation.
  public init(_ title: String, image: String, showDisclosure: Bool = false) {
    self.image = image
    self.title = title
    self.showDisclosure = showDisclosure
  }

  public var body: some View {
    HStack(spacing: 8) {
      Image(systemName: image)
        .font(.headline)
        .frame(minWidth: 25, alignment: .leading)
        .accessibility(hidden: true)

      Text(title)

      Spacer()

      if showDisclosure {
        Image(systemName: "chevron.right")
          .accessibility(hidden: true)
      }
    }
    .padding(.vertical
    .foregroundColor(.accentColor)
  }
}

这个视图可以用在显示应用程序版本或版权的地方。在这种情况下,我们默认隐藏了披露图标。由于我们想在框架本身之外访问该视图并在我们自己的应用程序中使用它,我们将struct 的访问级别改为public

另一个用例是对某一行进行的操作。创建SettingsActionRow 文件,并添加以下内容。

public struct SettingsActionRow: View {
  private var image: String
  private var title: String
  private var action: () -> ()

  /// A generic settings row which can be customised according to your needs.
  /// - Parameters:
  ///   - title: The title of the row.
  ///   - image: The SF symbol for the row.
  ///   - action: The custom action that you want to perform on tapping the row.
  public init(_ title: String, image: String, action: @escaping () -> ()) {
    self.image = image
    self.title = title
    self.action = action
  }

  public var body: some View {
    Button(action: action) {
      SettingsRow(title, image: image, showDisclosure: true)
    }
    .buttonStyle(PlainButtonStyle())
  }
}

客户端代码为其提供一个动作;例如,在商店中审查应用程序或打开应用程序的社交账户。

为了导航到另一个视图,我们创建另一个名为SettingsNavigationRow 的视图。

public struct SettingsNavigationRow<Destination: View>: View {
  private var title: String
  private var image: String
  private var destination: Destination

  /// A generic settings row which can be customised according to your needs.
  /// - Parameters:
  ///   - title: The title of the row.
  ///   - image: The SF symbol for the row.
  ///   - destination: The view to navigate to, after tapping the row.
  public init(_ title: String, image: String, destination: Destination) {
    self.image = image
    self.title = title
    self.destination = destination
  }

  public var body: some View {
    NavigationLink(destination: destination) {
      SettingsRow(title, image: image, showDisclosure: true)
    }
    .buttonStyle(PlainButtonStyle())
  }
}

在几个类似的行之后,我们使用二级背景色对它们进行分组,就像在iOS设置屏幕中一样。添加以下修改器。

public extension View {
  func settingsBackground(cornerRadius: CGFloat = 16,
                          innerPadding: CGFloat = 8,
                          outerPadding: CGFloat = 16) -> some View {
    self
      .padding(.horizontal, 16)
      .padding(.vertical, innerPadding)
      .background(RoundedRectangle(cornerRadius: cornerRadius,
                                   style: .continuous)
                    .fill(Color(.secondarySystemBackground)))
      .padding(outerPadding)
  }
}

这样,我们就创建了第一个框架,准备在我们的应用程序中加以利用了

创建一个新的项目

打开Xcode,选择创建一个新的Xcode项目,并选择iOS标题下的App模板。

Create New Xcode Project App

按如下方式填写模板选项,然后点击下一步

  • 产品名称。Stocktance
  • 组织名称。随意填写
  • 组织标识符。你用于你的应用程序的标识符
  • 界面。SwiftUI
  • 生命周期。SwiftUI应用程序
  • 语言。Swift
  • 确保你已经取消了对使用核心数据包括单元测试UI 测试选项的勾选。

Xcode Create New App Menu

选择一个目录来保存我们的项目,然后点击创建

现在我们的项目已经准备好了,我们把框架导入到我们的应用程序中。

将框架导入到项目中

有两种方法可以将项目添加到你的应用程序中。

  • 将框架拖入项目导航器,然后将框架添加到目标中
  • 将框架添加到项目中,然后再将框架添加到目标中

两者的类型相似,所以我们更倾向于后一种选择。在应用程序中,从项目导航器中选择项目,选择Stocktance目标,然后滚动到框架、库和嵌入式内容

Xcode Frameworks, Libraries, and Embedded Content

点击加号按钮,点击添加其他...并选择添加文件...

Xcode Add Other Add Files

导航到SettingsKit文件夹并选择它。我们已经将该框架添加到项目中。要把它添加到我们的目标中,再次点击加号按钮,你会在上面找到SettingsKit.framework。选择它以将其添加到我们的目标中。

Xcode SettingsKit.framework

现在,我们已经成功地将该框架添加到我们的应用程序中了!是时候使用它了。是时候使用它了!

在项目中使用该框架

在Stocktance中创建一个新的SwiftUI文件,名为SettingsView ,在文件的顶部,导入我们的框架。

import SettingsKit

就像我们导入苹果的SwiftUI框架来利用他们所提供的一切,我们导入我们的框架来创建设置视图。

将以下内容添加到SettingsView

struct SettingsView: View {
  let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String

  var body: some View {
    NavigationView {
      ScrollView {
        VStack {
          SettingsNavigationRow("Account", image: "person.crop.circle",
                                destination: Text("Accounts Screen"))

          SettingsNavigationRow("Phone Numbers", image: "number.circle",
                                destination: Text("Phone Screen"))

          SettingsNavigationRow("Notifications", image: "bell.circle",
                                destination: Text("Notifications Screen"))
        }
        .settingsBackground()

        VStack {
          SettingsRow("App Version \(appVersion)", image: "doc.append")
        }
        .settingsBackground()
      }
      .navigationTitle("Settings")
    }
  }
}

通过几行代码,感谢我们之前创建的框架,我们为我们的设置屏幕创建了简单的视图。你也可以在任何其他应用程序中使用这个框架,以保持你的设置的一致性。

要在应用程序中添加SettingsView ,在ContentView.swift中复制以下内容。

struct Stock {
  var name: String
  var price: Double
}

extension Stock {
  static let testStocks = [Stock(name: "Banana", price: 125),                           Stock(name: "TapeBook", price: 320),                           Stock(name: "Ramalon", price: 3200)]
}

struct ContentView: View {
  var body: some View {
    NavigationView {
      List(Stock.testStocks, id: \.name, rowContent: WatchlistRow.init)
        .navigationTitle("Stocktance")
        .toolbar {
          NavigationLink(destination: SettingsView()) {
            Image(systemName: "gear")
          }
        }
    }
    .accentColor(.purple)
  }
}

struct WatchlistRow: View {
  var stock: Stock

  var body: some View {
    HStack {
      Text(stock.name)

      Spacer()

      Text("$" + String(format: "%.2f", stock.price))
        .foregroundColor(.white)
        .padding(8)
        .background(RoundedRectangle(cornerRadius: 8).fill(Color(.systemGreen)))
    }
    .padding(.vertical)
  }
}

运行该应用程序,看看你的框架代码是如何运作的!

Xcode Stocktance Settings Xcode Stocktance Example

结论

随着你的应用程序的扩展,将代码分解成单独的组件和可重用的大块的框架,是一个很好的计划。例如,你可以将网络层作为一个框架,与主应用程序隔离开来。或者用一个AnalyticsKit来处理分析问题。如果提供者发生变化,你只需要在框架中进行修改,因为主要的实现是与应用程序分离的。

对于将你的框架作为开源库分享或与团队内部分享,你可以使用Swift Package Manager来管理代码的分发。

The postHow to create a framework in Swiftappeared first onLogRocket Blog.