@@ -6,7 +6,7 @@ Copyright 2023 - Present, Shopify Inc.
66Permission is hereby granted, free of charge, to any person obtaining a copy
77of this software and associated documentation files (the "Software"), to deal
88in the Software without restriction, including without limitation the rights
9- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+ o use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1010copies of the Software, and to permit persons to whom the Software is
1111furnished to do so, subject to the following conditions:
1212
@@ -25,136 +25,135 @@ import Foundation
2525import ShopifyCheckoutSheetKit
2626
2727/**
28- * Shared event serialization utilities for converting ShopifyCheckoutSheetKit events
29- * to React Native compatible dictionaries.
30- */
31- class ShopifyEventSerialization {
32-
33- /**
34- * Encodes a Codable object to a JSON dictionary for React Native bridge.
35- */
36- static func encodeToJSON( from value: Codable ) -> [ String : Any ] {
37- let encoder = JSONEncoder ( )
38-
39- do {
40- let jsonData = try encoder. encode ( value)
41- if let jsonObject = try JSONSerialization . jsonObject ( with: jsonData, options: [ ] ) as? [ String : Any ] {
42- return jsonObject
43- }
44- } catch {
45- print ( " Error encoding to JSON object: \( error) " )
46- }
47- return [ : ]
48- }
49-
50- /**
51- * Converts a JSON string to a dictionary.
52- */
53- static func stringToJSON( from value: String ? ) -> [ String : Any ] ? {
54- guard let data = value? . data ( using: . utf8, allowLossyConversion: false ) else { return [ : ] }
55- do {
56- return try JSONSerialization . jsonObject ( with: data, options: . mutableContainers) as? [ String : Any ]
57- } catch {
58- print ( " Failed to convert string to JSON: \( error) " , value ?? " nil " )
59- return [ : ]
60- }
61- }
62-
63- /**
64- * Converts a CheckoutCompletedEvent to a React Native compatible dictionary.
65- */
66- static func serialize( checkoutCompletedEvent event: CheckoutCompletedEvent ) -> [ String : Any ] {
67- return encodeToJSON ( from: event)
68- }
69-
70- /**
71- * Converts a PixelEvent to a React Native compatible dictionary.
72- */
73- static func serialize( pixelEvent event: PixelEvent ) -> [ String : Any ] {
74- switch event {
75- case . standardEvent( let standardEvent) :
76- let encoded = encodeToJSON ( from: standardEvent)
77- return [
78- " context " : encoded [ " context " ] ?? NSNull ( ) ,
79- " data " : encoded [ " data " ] ?? NSNull ( ) ,
80- " id " : encoded [ " id " ] ?? NSNull ( ) ,
81- " name " : encoded [ " name " ] ?? NSNull ( ) ,
82- " timestamp " : encoded [ " timestamp " ] ?? NSNull ( ) ,
83- " type " : " STANDARD "
84- ]
85-
86- case . customEvent( let customEvent) :
87- return [
88- " context " : encodeToJSON ( from: customEvent. context) ,
89- " customData " : stringToJSON ( from: customEvent. customData) ?? NSNull ( ) ,
90- " id " : customEvent. id,
91- " name " : customEvent. name,
92- " timestamp " : customEvent. timestamp,
93- " type " : " CUSTOM "
94- ]
95- }
96- }
97-
98- static func serialize( clickEvent url: URL ) -> [ String : URL ] {
28+ * Shared event serialization utilities for converting ShopifyCheckoutSheetKit events
29+ * to React Native compatible dictionaries.
30+ */
31+ enum ShopifyEventSerialization {
32+ /**
33+ * Encodes a Codable object to a JSON dictionary for React Native bridge.
34+ */
35+ static func encodeToJSON( from value: Codable ) -> [ String : Any ] {
36+ let encoder = JSONEncoder ( )
37+
38+ do {
39+ let jsonData = try encoder. encode ( value)
40+ if let jsonObject = try JSONSerialization . jsonObject ( with: jsonData, options: [ ] ) as? [ String : Any ] {
41+ return jsonObject
42+ }
43+ } catch {
44+ print ( " Error encoding to JSON object: \( error) " )
45+ }
46+ return [ : ]
47+ }
48+
49+ /**
50+ * Converts a JSON string to a dictionary.
51+ */
52+ static func stringToJSON( from value: String ? ) -> [ String : Any ] ? {
53+ guard let data = value? . data ( using: . utf8, allowLossyConversion: false ) else { return [ : ] }
54+ do {
55+ return try JSONSerialization . jsonObject ( with: data, options: . mutableContainers) as? [ String : Any ]
56+ } catch {
57+ print ( " Failed to convert string to JSON: \( error) " , value ?? " nil " )
58+ return [ : ]
59+ }
60+ }
61+
62+ /**
63+ * Converts a CheckoutCompletedEvent to a React Native compatible dictionary.
64+ */
65+ static func serialize( checkoutCompletedEvent event: CheckoutCompletedEvent ) -> [ String : Any ] {
66+ return encodeToJSON ( from: event)
67+ }
68+
69+ /**
70+ * Converts a PixelEvent to a React Native compatible dictionary.
71+ */
72+ static func serialize( pixelEvent event: PixelEvent ) -> [ String : Any ] {
73+ switch event {
74+ case let . standardEvent( standardEvent) :
75+ let encoded = encodeToJSON ( from: standardEvent)
76+ return [
77+ " context " : encoded [ " context " ] ?? NSNull ( ) ,
78+ " data " : encoded [ " data " ] ?? NSNull ( ) ,
79+ " id " : encoded [ " id " ] ?? NSNull ( ) ,
80+ " name " : encoded [ " name " ] ?? NSNull ( ) ,
81+ " timestamp " : encoded [ " timestamp " ] ?? NSNull ( ) ,
82+ " type " : " STANDARD "
83+ ]
84+
85+ case let . customEvent( customEvent) :
86+ return [
87+ " context " : encodeToJSON ( from: customEvent. context) ,
88+ " customData " : stringToJSON ( from: customEvent. customData) ?? NSNull ( ) ,
89+ " id " : customEvent. id,
90+ " name " : customEvent. name,
91+ " timestamp " : customEvent. timestamp,
92+ " type " : " CUSTOM "
93+ ]
94+ }
95+ }
96+
97+ static func serialize( clickEvent url: URL ) -> [ String : URL ] {
9998 return [ " url " : url]
100- }
101-
102- /**
103- * Converts a CheckoutError to a React Native compatible dictionary.
104- * Handles all specific error types with proper type information.
105- */
106- static func serialize( checkoutError error: CheckoutError ) -> [ String : Any ] {
107- switch error {
108- case . checkoutExpired( let message, let code, let recoverable) :
109- return [
110- " __typename " : " CheckoutExpiredError " ,
111- " message " : message,
112- " code " : code. rawValue,
113- " recoverable " : recoverable
114- ]
115-
116- case . checkoutUnavailable( let message, let code, let recoverable) :
117- switch code {
118- case . clientError( let clientErrorCode) :
119- return [
120- " __typename " : " CheckoutClientError " ,
121- " message " : message,
122- " code " : clientErrorCode. rawValue,
123- " recoverable " : recoverable
124- ]
125- case . httpError( let statusCode) :
126- return [
127- " __typename " : " CheckoutHTTPError " ,
128- " message " : message,
129- " code " : " http_error " ,
130- " statusCode " : statusCode,
131- " recoverable " : recoverable
132- ]
133- }
134-
135- case . configurationError( let message, let code, let recoverable) :
136- return [
137- " __typename " : " ConfigurationError " ,
138- " message " : message,
139- " code " : code. rawValue,
140- " recoverable " : recoverable
141- ]
142-
143- case . sdkError( let underlying, let recoverable) :
144- return [
145- " __typename " : " InternalError " ,
146- " code " : " unknown " ,
147- " message " : underlying. localizedDescription,
148- " recoverable " : recoverable
149- ]
150-
151- @unknown default :
152- return [
153- " __typename " : " UnknownError " ,
154- " code " : " unknown " ,
155- " message " : error. localizedDescription,
156- " recoverable " : error. isRecoverable
157- ]
158- }
159- }
99+ }
100+
101+ /**
102+ * Converts a CheckoutError to a React Native compatible dictionary.
103+ * Handles all specific error types with proper type information.
104+ */
105+ static func serialize( checkoutError error: CheckoutError ) -> [ String : Any ] {
106+ switch error {
107+ case let . checkoutExpired( message, code, recoverable) :
108+ return [
109+ " __typename " : " CheckoutExpiredError " ,
110+ " message " : message,
111+ " code " : code. rawValue,
112+ " recoverable " : recoverable
113+ ]
114+
115+ case let . checkoutUnavailable( message, code, recoverable) :
116+ switch code {
117+ case let . clientError( clientErrorCode) :
118+ return [
119+ " __typename " : " CheckoutClientError " ,
120+ " message " : message,
121+ " code " : clientErrorCode. rawValue,
122+ " recoverable " : recoverable
123+ ]
124+ case let . httpError( statusCode) :
125+ return [
126+ " __typename " : " CheckoutHTTPError " ,
127+ " message " : message,
128+ " code " : " http_error " ,
129+ " statusCode " : statusCode,
130+ " recoverable " : recoverable
131+ ]
132+ }
133+
134+ case let . configurationError( message, code, recoverable) :
135+ return [
136+ " __typename " : " ConfigurationError " ,
137+ " message " : message,
138+ " code " : code. rawValue,
139+ " recoverable " : recoverable
140+ ]
141+
142+ case let . sdkError( underlying, recoverable) :
143+ return [
144+ " __typename " : " InternalError " ,
145+ " code " : " unknown " ,
146+ " message " : underlying. localizedDescription,
147+ " recoverable " : recoverable
148+ ]
149+
150+ @unknown default :
151+ return [
152+ " __typename " : " UnknownError " ,
153+ " code " : " unknown " ,
154+ " message " : error. localizedDescription,
155+ " recoverable " : error. isRecoverable
156+ ]
157+ }
158+ }
160159}
0 commit comments