Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,22 @@ fastlane/test_output

iOSInjectionProject/
.DS_Store


# Swift Package Manager
/.build
/Packages
Package.resolved

# 如果你用 Xcode 打开 Package.swift,会生成 .swiftpm
.swiftpm/xcode

# Playground 支持
timeline.xctimeline
playground.xcworkspace

# SwiftPM artifact cache (Swift 5.8+,如果用到了 binary target)
.artifacts

# Xcode Preview snapshots
*.preview-thumbnails
1 change: 1 addition & 0 deletions Sources/SmartCodable/Core/JSONEncoder/EncodingCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class EncodingCache: Cachable {

var snapshot = EncodingSnapshot()
snapshot.objectType = object
snapshot.codingPath = codingPath
snapshot.transformers = object.mappingForValue()
snapshots.append(snapshot)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,10 @@ extension _SpecialTreatmentEncoder {
return try self.wrapObject(object as! [String: Encodable], for: additionalKey)
default:

impl.cache.cacheSnapshot(for: E.self, codingPath: codingPath)

let encoder = self.getEncoder(for: additionalKey)
encoder.cache.cacheSnapshot(for: E.self, codingPath: encoder.codingPath)
try encodable.encode(to: encoder)
impl.cache.removeSnapshot(for: E.self)
encoder.cache.removeSnapshot(for: E.self)

// If it is modified by SmartFlat, you need to encode to the upper layer to restore the data.
if encodable is FlatType {
Expand Down
121 changes: 121 additions & 0 deletions Tests/Example.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import XCTest
import SmartCodableInherit
import Foundation
@testable import SmartCodable


Expand Down Expand Up @@ -33,8 +35,36 @@ class Tests: XCTestCase {

}


func testJSONEncode() {
var dic: [String: Any] = [
"id": 563,
"owner_id": 264,
"title": "langwang004+82 ワークスペース",
"icon": "",
"type": 2,
"used_seat": 1,
"created_at": "2025-07-25T02:58:35Z",
]

let subscription: [String: Any] = [
"cancel_at_period_end": true,
"current_period_end_at": "2025-07-30T03:37:03Z",
"price_id": "personal_plan_annual_trial",
"status": "past_due"
]
dic["subscription"] = subscription as any Equatable

let model = WorkspaceModel.deserialize(from: dic)
XCTAssertNotNil(model)
let modelDic = model?.toDictionary(useMappedKeys: true)
XCTAssertNotNil(modelDic)
let res = deepEqualDict(dic, modelDic!)
XCTAssertTrue(res)
}
}


// SmartCodable
struct Smart: SmartCodable {
var name: String?
Expand Down Expand Up @@ -66,3 +96,94 @@ class SubModel: BaseModel {
return "我的名字是\(self.name)"
}()
}

// MARK: - Test JSON Encode
func deepEqual(_ lhs: Any, _ rhs: Any) -> Bool {
switch (lhs, rhs) {
case let (a as Int, b as Int): return a == b
case let (a as Double, b as Double): return a == b
case let (a as String, b as String): return a == b
case let (a as Bool, b as Bool): return a == b
case let (a as [String: Any], b as [String: Any]):
return deepEqualDict(a, b)
case let (a as [Any], b as [Any]):
return deepEqualArray(a, b)
case let (a as NSNumber, b as NSNumber):
return a == b
case (is NSNull, is NSNull):
return true
default:
return false
}
}

func deepEqualDict(_ lhs: [String: Any], _ rhs: [String: Any]) -> Bool {
guard lhs.count == rhs.count else { return false }
for (key, lValue) in lhs {
print("compare key: \(key), lValue: \(lValue)")
guard let rValue = rhs[key] else {
print("not found rValue for key: \(key), in rhs: \(rhs)")
return false
}
if !deepEqual(lValue, rValue) {
print("lValue: \(lValue) not equal to rValue: \(rValue)")
return false
}
}
print("key value equal in both")
return true
}

func deepEqualArray(_ lhs: [Any], _ rhs: [Any]) -> Bool {
guard lhs.count == rhs.count else { return false }
for (l, r) in zip(lhs, rhs) {
if !deepEqual(l, r) {
return false
}
}
return true
}

open class SCRootModel {

required public init() { }

open func didFinishMapping() {

}

open class func mappingForKey() -> [SmartKeyTransformer]? {
nil
}

open class func mappingForValue() -> [SmartValueTransformer]? {
nil
}
}


class WorkspaceModel: SCRootModel, SmartCodable {
var id: Int = 0
var owner_id: Int = 0
var title: String = ""
var icon: String = ""
var type: Int = 0
var used_seat: Int = 0
var created_at: String = ""
var subscription: WorkspaceSubscription?
}

class WorkspaceSubscription: SCRootModel, SmartCodable {
var cancelAtPeriodEnd: Bool = false
var currentPeriodEndAt: String = ""
var priceid: String = ""
var status: String = ""

override class func mappingForKey() -> [SmartKeyTransformer]? {
[
CodingKeys.cancelAtPeriodEnd <--- "cancel_at_period_end",
CodingKeys.currentPeriodEndAt <--- "current_period_end_at",
CodingKeys.priceid <--- "price_id",
]
}
}
Loading