SwiftMacros

一套实用的 Swift 宏集合,可帮助您正确且迅速地编写代码。

安装

.package(url: "https://github.com/ShenghaiWang/SwiftMacros.git", from: "2.0.0")

API 文档

描述
@Access 一个简单的 API,用于访问 UserDefaults、Keychain、NSCache 和 NSMapTable。
struct TestAccess {
static let cache = NSCache<NSString, AnyObject>()

// Please make sure the generic type is the same as the type of the variable
// Without defalut value
@Access<Bool?>(.userDefaults())
var isPaidUser: Bool?

// With default value
@Access< Bool>(.userDefaults())
var isPaidUser2: Bool = false

@Access<NSObject?>(.nsCache(TestAccess.cache))
var hasPaid: NSObject?

@Access<NSObject?>(.nsMapTable(TestAccess.mapTable))
var hasPaid2: NSObject?

@Access<TestStruct?>(.keychain)
var keychainValue: TestStruct?
}
@AddAssociatedValueVariable 添加变量以检索关联的值
@AddAssociatedValueVariable
enum MyEnum {
case first
case second(Int)
case third(String, Int)
case forth(a: String, b: Int), forth2(String, Int)
case fifth(() -> Void)
}
@AddInit 为类/结构体/actor 生成初始化器。具有可选类型的变量将具有 nil 作为默认值。如果想要生成模拟数据,请使用 withMock: true
对于自定义数据类型,它将使用 Type.mock。如果不存在此值,则需要自己定义此值,或使用 @Mock@AddInit(withMock: true) 来生成此变量。
@AddPublisher 生成一个 Combine 发布者到 Combine 主题,以避免过度暴露主题变量
@AddPublisher
private let mySubject = PassthroughSubject<Void, Never>()
@AddInit
struct InitStruct {
let a: Int
let b: Int?
let c: (Int?) -> Void
let d: ((Int?) -> Void)?
}
@AddInit(withMock: true)
class AStruct {
let a: Float
}
#buildDate 从组件构建一个 Date
此解决方案添加了一个 resultBulder DateBuilder,如果喜欢构建器模式,可以直接使用。
注意:这是为了更简单的 API。请在需要效率的地方谨慎使用它。
let date = #buildDate(DateString("03/05/2003", dateFormat: "MM/dd/yyyy"),
Date(),
Month(10),
Year(1909),
YearForWeekOfYear(2025))
#buildURL 从组件构建一个 url。
此解决方案添加了一个 resultBulder URLBuilder,如果喜欢构建器模式,可以直接使用。
let url = #buildURL("http://google.com",
URLScheme.https,
URLQueryItems([.init(name: "q1", value: "q1v"), .init(name: "q2", value: "q2v")]))
let url2 = buildURL {
"http://google.com"
URLScheme.https
URLQueryItems([.init(name: "q1", value: "q1v"), .init(name: "q2", value: "q2v")])
}
#buildURLRequest 从组件构建一个 URLRequest。
此解决方案添加了一个 resultBulder URLRequestBuilder,如果喜欢构建器模式,可以直接使用。
let urlrequest = #buildURLRequest(url!, RequestTimeOutInterval(100))
let urlRequest2 = buildURLRequest {
url!
RequestTimeOutInterval(100)
}
@ConformToEquatable 为类类型添加 Equtable 一致性
请谨慎使用,详见 https://github.com/apple/swift-evolution/blob/main/proposals/0185-synthesize-equatable-hashable.md#synthesis-for-class-types-and-tuples
@AddInit
@ConformToEquatable
class AClass {
let a: Int?
let b: () -> Void
}
@ConformToHashable 为类类型添加 Hashable 一致性
请谨慎使用,详见 https://github.com/apple/swift-evolution/blob/main/proposals/0185-synthesize-equatable-hashable.md#synthesis-for-class-types-and-tuples
@AddInit
@ConformToHashable
class AClass {
let a: Int?
let b: () -> Void
}
#encode 使用 JSONEncoder 将 Encodable 编码为数据
#encode(value)
#decode 使用 JSONDecoder 将 Decodable 解码为类型化的值
#decode(TestStruct.self, from: data)
#formatDate 将日期格式化为字符串
#formatDate(Date(), dateStyle: .full)
#formatDateComponents 将日期差异/时间间隔/日期组件格式化为字符串
#formatDateComponents(from: Date(), to: Date(), allowedUnits: [.day, .hour, .minute, .second])
#formatDateComponents(fromInterval: 100, allowedUnits: [.day, .hour, .minute, .second])
#formatDateComponents(fromComponents: DateComponents(hour: 10), allowedUnits: [.day, .hour, .minute, .second])
#formatDateInterval 将两个日期格式化为间隔字符串
#formatDateInterval(from: Date(), to: Date(), dateStyle: .short)
@Mock 使用附加的初始化器生成一个静态变量 mock
对于自定义数据类型,它将使用 Type.mock。如果不存在此值,则需要自己定义此值,或使用 @Mock@AddInit(withMock: true) 来生成此变量。
class AStruct {
let a: Float
@Mock(type: AStruct.self)
init(a: Float) {
self.a = a
}
}
#postNotification 一种发布通知的简单方法
#postNotification(.NSCalendarDayChanged)
@Singleton 为 struct 和 class 类型生成 Swift 单例代码
@Singleton
struct A {}

待添加

请随时在此处添加您想要的宏。欢迎所有 PR(无论是否带有实现)。

描述
@ 您的新宏创意