Implemented deserializing BankList.json on iOS (but packaging BankList.json doesn't work yet, manually linked it to iOSApp project)

This commit is contained in:
dankito 2020-07-11 17:08:24 +02:00
parent 1bef1904f9
commit 57ced4a88b
7 changed files with 122 additions and 30 deletions

View File

@ -0,0 +1,28 @@
package net.dankito.utils.multiplatform
import platform.Foundation.NSArray
import platform.Foundation.NSDictionary
fun <T> NSArray.toList(): List<T> {
val result = mutableListOf<T>()
for (i in 0L until this.count.toLong()) {
result.add(this.objectAtIndex(i.toULong()) as T)
}
return result
}
fun NSDictionary.getString(key: String): String? {
return this.objectForKey(key) as? String
}
fun NSDictionary.getString(key: String, defaultValue: String): String {
return this.getString(key) ?: defaultValue
}
fun NSDictionary.getStringOrEmpty(key: String): String {
return this.getString(key, "")
}

View File

@ -24,7 +24,7 @@ kotlin {
fromPreset(iOSTarget, 'ios') {
binaries {
framework {
baseName = "fints4k"
baseName = "BankFinder"
}
}
}
@ -35,6 +35,8 @@ kotlin {
commonMain {
dependencies {
implementation kotlin("stdlib-common")
implementation project(":common")
}
}

View File

@ -1,18 +1,8 @@
package net.dankito.banking.bankfinder
import net.dankito.utils.serialization.JacksonJsonSerializer
import org.slf4j.LoggerFactory
abstract class BankFinderBase : IBankFinder {
companion object {
const val BankListFileName = "BankList.json"
private val log = LoggerFactory.getLogger(InMemoryBankFinder::class.java)
}
protected abstract fun findBankByNameOrCityForNonEmptyQuery(query: String): List<BankInfo>
abstract fun searchBankByBic(bic: String): BankInfo?
@ -47,24 +37,8 @@ abstract class BankFinderBase : IBankFinder {
}
protected open fun loadBankListFile(): List<BankInfo> {
try {
val bankListString = readBankListFile()
JacksonJsonSerializer().deserializeList(bankListString, BankInfo::class.java)?.let {
return it
}
} catch (e: Exception) {
log.error("Could not load bank list", e)
}
return listOf()
}
protected open fun readBankListFile(): String {
val inputStream = BankFinderBase::class.java.classLoader.getResourceAsStream(BankListFileName)
return inputStream.bufferedReader().readText()
protected open fun loadBankList(): List<BankInfo> {
return BankListDeserializer().loadBankList()
}
}

View File

@ -0,0 +1,8 @@
package net.dankito.banking.bankfinder
expect class BankListDeserializer() {
fun loadBankList(): List<BankInfo>
}

View File

@ -58,7 +58,7 @@ open class InMemoryBankFinder() : BankFinderBase(), IBankFinder {
return it
}
val bankList = loadBankListFile()
val bankList = loadBankList()
this.bankListField = bankList

View File

@ -0,0 +1,44 @@
package net.dankito.banking.bankfinder
import net.dankito.utils.multiplatform.getString
import net.dankito.utils.multiplatform.getStringOrEmpty
import net.dankito.utils.multiplatform.toList
import platform.Foundation.*
actual class BankListDeserializer {
actual fun loadBankList(): List<BankInfo> {
val bundle = NSBundle.mainBundle
bundle.pathForResource("BankList", "json")?.let { bankListJsonPath ->
NSData.dataWithContentsOfFile(bankListJsonPath, NSDataReadingMappedIfSafe, null)?.let { bankListData ->
NSJSONSerialization.JSONObjectWithData(bankListData, NSJSONReadingMutableContainers, null)?.let { bankListJson ->
(bankListJson as? NSArray)?.let {
return bankListJson.toList<NSDictionary>().map {
mapToBankInfo(it)
}
}
}
}
}
return listOf()
}
private fun mapToBankInfo(bankInfoDict: NSDictionary): BankInfo {
return BankInfo(
bankInfoDict.getStringOrEmpty("name"),
bankInfoDict.getStringOrEmpty("bankCode"),
bankInfoDict.getStringOrEmpty("bic"),
bankInfoDict.getStringOrEmpty("postalCode"),
bankInfoDict.getStringOrEmpty("city"),
bankInfoDict.getStringOrEmpty("checksumMethod"),
bankInfoDict.getString("pinTanAddress"),
bankInfoDict.getString("pinTanVersion"),
bankInfoDict.getString("oldBankCode")
)
}
}

View File

@ -0,0 +1,36 @@
package net.dankito.banking.bankfinder
import net.dankito.utils.multiplatform.log.LoggerFactory
import net.dankito.utils.serialization.JacksonJsonSerializer
actual class BankListDeserializer {
companion object {
const val BankListFileName = "BankList.json"
private val log = LoggerFactory.getLogger(InMemoryBankFinder::class)
}
actual fun loadBankList(): List<BankInfo> {
try {
val bankListString = readBankListFile()
JacksonJsonSerializer().deserializeList(bankListString, BankInfo::class.java)?.let {
return it
}
} catch (e: Exception) {
log.error(e) { "Could not load bank list" }
}
return listOf()
}
fun readBankListFile(): String {
val inputStream = BankFinderBase::class.java.classLoader.getResourceAsStream(BankListFileName)
return inputStream.bufferedReader().readText()
}
}