对于上下文:我使用kotlin多平台与我的后端为我的两个应用程序进行通信,我也试图遵循清洁架构+ MVVM。我的多平台项目包含我的数据层(存储库和dtos),我的应用程序项目包含表示层和领域层(VC,视图模型,用例)。
我想在多平台项目中模拟我的存储库。
我有一个类(DTO)在我的Kotlin多平台项目,看起来像这样
@Serializable
data class LoginResponse(val data: LoginResponseBody){
@Serializable
data class LoginResponseBody(
var accessToken: String,
var lastChannel: String? = null,
var lastDateTime: String? = null,
var userId: String? = null,
var transactionalKeyStatus: String? = null,
var accessStatus: String? = null
)
}
当我将这个多平台项目添加到我的xcode项目中时,对象转换为:
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("LoginResponse")))
@interface SharedEmaLoginResponse : SharedEmaBase
- (instancetype)initWithData:(SharedEmaLoginResponseLoginResponseBody *)data __attribute__((swift_name("init(data:)"))) __attribute__((objc_designated_initializer));
- (SharedEmaLoginResponseLoginResponseBody *)component1 __attribute__((swift_name("component1()")));
- (SharedEmaLoginResponse *)doCopyData:(SharedEmaLoginResponseLoginResponseBody *)data __attribute__((swift_name("doCopy(data:)")));
- (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)")));
- (NSUInteger)hash __attribute__((swift_name("hash()")));
- (NSString *)description __attribute__((swift_name("description()")));
@property (readonly) SharedEmaLoginResponseLoginResponseBody *data __attribute__((swift_name("data")));
@end;
我认为类LoginResponse将符合'可解码',但它没有,这是我的假库看起来像在我的xcode项目
final class LoginRepositoryTest : XCTestCase, IAuthRepository {
var hasError = false
func login(loginRequest: LoginRequest, success: @escaping (LoginResponse) -> Void, failure: @escaping (ErrorResponse) -> Void, completionHandler: @escaping (KotlinUnit?, Error?) -> Void) {
if hasError {
failure(ErrorResponse(messages: []))
} else {
let data = loadStub(name: "loginResponse", extension: "json")
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let loginData = try! decoder.decode(LoginResponse.self, from: data)
success(loginData)
}
}
func getKoin() -> Koin_coreKoin {}
}
误差
实例方法'decode(_:from:)'要求'LoginResponse'符合'Decodable'
我想我有两个选择:
- 我使kotlin类符合'可解码'
- 我找到了一种方法将JSON转换为该对象而不使用可解码
任何帮助都是感激的
Kotlin序列化并不意味着向类确认Decodable
协议。它意味着在kotlin中使用kotlin序列化,如下所示:
val response: LoginResponse = Json.decodeFromString(
LoginResponse.serializer(),
string
)
注。最初您可以使用Json.decodeFromString<LoginResponse>(string)
,但据我所知,这还不支持多平台
网络和JSON解析是最容易在KMM上完成的事情,你也可以在那里编写测试,但如果你仍然需要直接从iOS使用它,你可以尝试以下包装器:
object JsonHelper {
@Throws(Throwable::class)
fun decodeRtcMsg(string: String) =
Json.decodeFromString(
RtcMsg.serializer(),
string
)
}
那么你可以从swift:
do {
try JsonHelper().decodeLoginResponse(string: "")
} catch {
print(error)
}
如果你真的需要Decodable
,我会创建Decodable
的expect/actual
:
// in common
expect interface Decodable
// on Android
actual interface Decodable
// on iOS
actual typealias Decodable = Decodable
然后为你的dto实现Decodable
。也许最好的例子是如何在共享代码中使用Parcelize
: https://github.com/icerockdev/moko-parcelize/blob/master/parcelize/src/androidMain/kotlin/dev/icerock/moko/parcelize/Parcelize.kt