Skip to content

Commit d8f6c60

Browse files
committed
Update encoder decoder to match quill structure
1 parent 0ab4ec6 commit d8f6c60

File tree

2 files changed

+87
-20
lines changed

2 files changed

+87
-20
lines changed

Sources/RichEditorSwiftUI/Data/Models/RichAttributes.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,12 @@ public struct RichAttributes: Codable {
7373
case background = "background"
7474
case align = "align"
7575
case link = "link"
76-
case image = "image"
76+
/**
77+
Commented as it should not be encode as we follow Quill Architecture so in that image is encoded
78+
in ``RichTextSpan.insert`` of span model
79+
80+
*/
81+
// case image = "image"
7782
}
7883

7984
public init(from decoder: Decoder) throws {
@@ -96,7 +101,12 @@ public struct RichAttributes: Codable {
96101
self.align = try values.decodeIfPresent(
97102
RichTextAlignment.self, forKey: .align)
98103
self.link = try values.decodeIfPresent(String.self, forKey: .link)
99-
self.image = try values.decodeIfPresent(String.self, forKey: .image)
104+
/**
105+
Commented as it should not be decode as we follow Quill Structure so in that image is decoded
106+
in ``RichTextSpan.insert`` of span's json and we add it by copying it
107+
108+
*/
109+
// self.image = try values.decodeIfPresent(String.self, forKey: .image)
100110
}
101111
}
102112

Sources/RichEditorSwiftUI/Data/Models/RichText.swift

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,85 @@ import Foundation
1010
typealias RichTextSpans = [RichTextSpan]
1111

1212
public struct RichText: Codable {
13-
public let spans: [RichTextSpan]
13+
public let spans: [RichTextSpan]
1414

15-
public init(spans: [RichTextSpan] = []) {
16-
self.spans = spans
17-
}
15+
public init(spans: [RichTextSpan] = []) {
16+
self.spans = spans
17+
}
1818

19-
func encodeToData() throws -> Data {
20-
return try JSONEncoder().encode(self)
21-
}
19+
func encodeToData() throws -> Data {
20+
return try JSONEncoder().encode(self)
21+
}
2222
}
2323

2424
public struct RichTextSpan: Codable {
25-
// public var id: String = UUID().uuidString
26-
public let insert: String
27-
public let attributes: RichAttributes?
28-
29-
public init(
30-
insert: String,
31-
attributes: RichAttributes? = nil
32-
) {
33-
// self.id = id
34-
self.insert = insert
35-
self.attributes = attributes
25+
// public var id: String = UUID().uuidString
26+
public let insert: String
27+
public let attributes: RichAttributes?
28+
29+
public init(
30+
insert: String,
31+
attributes: RichAttributes? = nil
32+
) {
33+
// self.id = id
34+
self.insert = insert
35+
self.attributes = attributes
36+
}
37+
}
38+
39+
extension RichTextSpan {
40+
41+
// Custom Encoding
42+
public func encode(to encoder: Encoder) throws {
43+
var container = encoder.container(keyedBy: CodingKeys.self)
44+
45+
// If there is an image in the attributes, encode insert as an image object
46+
if let image = attributes?.image {
47+
let richTextImage = RichTextImage(image: image)
48+
try container.encode(richTextImage, forKey: .insert)
49+
} else {
50+
// Otherwise, just encode insert as a simple string
51+
try container.encode(insert, forKey: .insert)
3652
}
53+
54+
try container.encodeIfPresent(attributes, forKey: .attributes)
55+
}
56+
57+
// Custom Decoding
58+
public init(from decoder: Decoder) throws {
59+
let container = try decoder.container(keyedBy: CodingKeys.self)
60+
61+
var imageAttribute: String? = nil
62+
// Decode insert as a string and extract image form json's insert if available
63+
if let imageDict = try? container.decode([String: String].self, forKey: .insert),
64+
let image = imageDict["image"]
65+
{
66+
self.insert = " "
67+
// If insert contains an image, set insert to the image URL and set the image attribute
68+
imageAttribute = image
69+
} else {
70+
// If insert is just a string, set insert as usual
71+
self.insert = try container.decode(String.self, forKey: .insert)
72+
}
73+
let attributesInit = try container.decodeIfPresent(RichAttributes.self, forKey: .attributes)
74+
self.attributes = attributesInit?.copy(with: .image(imageAttribute), byAdding: true)
75+
76+
}
77+
78+
enum CodingKeys: String, CodingKey {
79+
case insert
80+
case attributes
81+
}
82+
}
83+
84+
internal struct RichTextImage: Codable {
85+
let image: String
86+
87+
enum CodingKeys: String, CodingKey {
88+
case image = "image"
89+
}
90+
91+
init(image: String) {
92+
self.image = image
93+
}
3794
}

0 commit comments

Comments
 (0)