Closed lifeisegg123 closed 5 months ago
Please attach code calls this package's api
I've called it like this, and this happened as well when I'm using shareTextTemplate
.
import { shareFeedTemplate } from '@react-native-kakao/share'
...
try {
shareFeedTemplate({
template: {
content: {
title: 'some title',
imageUrl: 'url to some image',
link: {
mobileWebUrl: 'url to some mobile web url',
webUrl: 'url to some web url',
androidExecutionParams: {
sample1: String(1),
sample2: String(10),
},
iosExecutionParams: {
sample1: String(1),
sample2: String(10),
},
},
},
},
})
} catch (e) {
console.error(e)
}
I've changed function like as shown below, it works.
private func generateTemplatable(
_ type: String,
_ defaultTemplate: inout [String: Any?]
) throws -> Templatable {
// Serialize specific nested keys
serializeNestedKeys(dict: &defaultTemplate, keys: ["content", "link", "androidExecutionParams"])
serializeNestedKeys(dict: &defaultTemplate, keys: ["content", "link", "iosExecutionParams"])
defaultTemplate["objectType"] = type
let data = try JSONSerialization.data(withJSONObject: defaultTemplate, options: .prettyPrinted)
switch type {
case "feed":
return try SdkJSONDecoder.custom.decode(FeedTemplate.self, from: data) as Templatable
case "list":
return try SdkJSONDecoder.custom.decode(ListTemplate.self, from: data) as Templatable
case "location":
return try SdkJSONDecoder.custom.decode(LocationTemplate.self, from: data) as Templatable
case "commerce":
return try SdkJSONDecoder.custom.decode(CommerceTemplate.self, from: data) as Templatable
case "text":
return try SdkJSONDecoder.custom.decode(TextTemplate.self, from: data) as Templatable
case "calendar":
return try SdkJSONDecoder.custom.decode(CalendarTemplate.self, from: data) as Templatable
default:
throw RNCKakaoError.unknown("Unknown templateType: \(type)")
}
}
private func serializeNestedKeys(dict: inout [String: Any?], keys: [String]) {
var keys = keys
guard let firstKey = keys.first else { return }
if keys.count == 1 {
if let value = dict[firstKey], !(value is NSNull),
JSONSerialization.isValidJSONObject(value),
let jsonData = try? JSONSerialization.data(withJSONObject: value, options: []),
let jsonString = String(data: jsonData, encoding: .utf8) {
dict[firstKey] = jsonString
}
} else {
keys.removeFirst()
if var nestedDict = dict[firstKey] as? [String: Any?] {
serializeNestedKeys(dict: &nestedDict, keys: keys)
dict[firstKey] = nestedDict
}
}
}
update. I guess this code might be more proper. it passes string as key1=value1&key2=value2
private func generateTemplatable(
_ type: String,
_ defaultTemplate: inout [String: Any?]
) throws -> Templatable {
// Use the new function to process the template
processTemplate(&defaultTemplate)
defaultTemplate["objectType"] = type
let data = try JSONSerialization.data(withJSONObject: defaultTemplate, options: .prettyPrinted)
switch type {
case "feed":
return try SdkJSONDecoder.custom.decode(FeedTemplate.self, from: data) as Templatable
case "list":
return try SdkJSONDecoder.custom.decode(ListTemplate.self, from: data) as Templatable
case "location":
return try SdkJSONDecoder.custom.decode(LocationTemplate.self, from: data) as Templatable
case "commerce":
return try SdkJSONDecoder.custom.decode(CommerceTemplate.self, from: data) as Templatable
case "text":
return try SdkJSONDecoder.custom.decode(TextTemplate.self, from: data) as Templatable
case "calendar":
return try SdkJSONDecoder.custom.decode(CalendarTemplate.self, from: data) as Templatable
default:
throw RNCKakaoError.unknown("Unknown templateType: \(type)")
}
}
private func processTemplate(_ template: inout [String: Any?]) {
let paramsToConvert = ["androidExecutionParams", "iosExecutionParams"]
for (key, value) in template {
if paramsToConvert.contains(key), let stringMapValue = value as? [String: String] {
template[key] = stringMapValue.queryParameters
} else if var nestedDict = value as? [String: Any?] {
processTemplate(&nestedDict)
template[key] = nestedDict
} else if var arrayValue = value as? [[String: Any?]] {
for i in 0..<arrayValue.count {
processTemplate(&arrayValue[i])
}
template[key] = arrayValue
} else if var arrayValue = value as? [Any?] {
for i in 0..<arrayValue.count {
if var nestedDict = arrayValue[i] as? [String: Any?] {
processTemplate(&nestedDict)
arrayValue[i] = nestedDict
}
}
template[key] = arrayValue
}
}
}
FYI)
JSONDecoder(extends from SdkJSONDecoder.custom)
references the data type of struct fields.
The (android|ios)ExecutionParams
property declared in the Link
has String type, not Map, unlike Android.
Also, documentation says that if you pass it as a String, we should pass it as a query string, so above code change is appropriate.
I see, thanks for the investigation. I’ll fix it soon.
Rather than parsing the NSDictionary in iOS, I’ll swap the values of these keys in JS.
This should be fixed in 2.2.5
Is there an existing issue for this?
Name, Version of @react-native-kakao/*
share, 2.2.4
Version of react-native
0.73.6
What os are you seeing the problem on?
iOS
What device types are you seeing the problem on?
Physcial Device
What architecture types of react native are you seeing the problem on?
Old Architecture(Bridge)
Version of device(android API, iOS OS version, etc...)
iOS 17.5.1
Expo App
What happened?
The
shareFeedTemplate
method throws an error when using{ios | android}ExecutionParams
only on iOS:[Error: 올바른 포맷이 아니기 때문에 해당 데이터를 읽을 수 없습니다.]
Here’s a sample structure I pass as an argument:
When I wrap the object with
JSON.stringify
to pass it as a string, it works fine on iOS but not on Android.I think this may happen because the Android & Flutter Kakao SDKs accept
Map<string, string>
(reference), but others expect aString
.Relevant a package.json.
No response
Relevant log output
No response
Code of Conduct