Kotlin Native iOS 字符串格式化与可变参数

     2023-04-15     105

关键词:

【中文标题】Kotlin Native iOS 字符串格式化与可变参数【英文标题】:Kotlin Native iOS string formatting with vararg 【发布时间】:2021-02-06 05:37:16 【问题描述】:

基于this issue关于使用NSString格式化我尝试在使用vararg时实现格式化的多平台实现,到目前为止没有运气。

我做了什么

添加了 FoundationInterop.def
language = Objective-C
---
#import <Foundation/NSString.h>

NSString* format(NSString* format, ...) 
    va_list args;
    va_start(args, format);
    NSString* result = [[NSString alloc] initWithFormat:format arguments:args];
    va_end(args);
    return result;

在 gradle 中编译
targets 
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos")  \
         ? presets.iosArm64 : presets.iosX64

        // https://kotlinlang.org/docs/reference/mpp-dsl-reference.html#native-targets
        fromPreset(iOSTarget, 'ios') 
            binaries 
            

            compilations.main.cinterops 
                FoundationInterop 
                
            
        
    
commonMain 中创建StringExtensions.kt
expect class StringType

expect fun String.format(format: String, vararg args: Any?): StringType?
iosMain
actual typealias StringType = String

/**
 * https://github.com/JetBrains/kotlin-native/issues/1834
 */
actual fun String.format(format: String, vararg args: Any?): StringType? 
    return FoundationInterop.format(format, args as Any)

示例
val fmt = "http://geomag.bgs.ac.uk/web_service/GMModels/igrf/13/?latitude=%f&longitude=%f&altitude=0&date=%d-%02d-%02d&format=json"
val url = fmt.format(urlFmt, 59.127934932762166, 38.00503518930868, 2020, 1, 3)
输出 - 如您所见,由于某种原因没有发生值替换
http://geomag.bgs.ac.uk/web_service/GMModels/igrf/13/?latitude=0.000000&longitude=0.000000&altitude=0&date=43344272-198763328-00&format=json

编辑

stringWithFormat 给出相同的结果

actual fun String.format(format: String, vararg args: Any?): StringType? 
    return NSString.stringWithFormat(format, args as Any)

编辑 2

创建问题https://youtrack.jetbrains.com/issue/KT-42925

【问题讨论】:

不是您的问题的答案,我想检查它为什么不起作用,但您提供的问题现已关闭:从 1.3.40 开始,可以直接使用initWithFormat. @shadowsheep 感谢您指出这一点,但它也不起作用,请参阅我的编辑 @shadowsheep 这个方法在我们传递像NSString.stringWithFormat("%@ %@ %d", "один" as NSString, "two" as NSString, 3) 这样的参数时有效,但不适用于vararg 知道了。现在更清楚了;)。所以我可以建议“格式化”你的格式和你的可变参数,以便函数相应地工作,在 iOS 内部真正有趣。 @shadowsheep 会是什么样子? 【参考方案1】:

我确认你所说的 NSString.stringWithFormat。正如我们在 JB 官方答案中所读到的那样,该功能缺失 Svyatoslav Scherbina,我们可以在这里关注您的问题:KT-42925

作为一个糟糕的解决方法,我提出了类似的建议(警告:不详尽,没有很多索引计数检查...)

import platform.Foundation.NSString
import platform.Foundation.stringWithFormat

actual typealias StringType = String

actual fun String.format(format: String, vararg args: Any?): StringType? 
    var returnString = ""
    val regEx = "%[\\d|.]*[sdf]|[%]".toRegex()
    val singleFormats = regEx.findAll(format).map 
        it.groupValues.first()
    .asSequence().toList()
    val newStrings = format.split(regEx)
    for (i in 0 until args.count()) 
        val arg = args[i]
        returnString += when (arg) 
            is Double -> 
                NSString.stringWithFormat(newStrings[i] + singleFormats[i], args[i] as Double)
            
            is Int -> 
                NSString.stringWithFormat(newStrings[i] + singleFormats[i], args[i] as Int)
            
            else -> 
                NSString.stringWithFormat(newStrings[i] + "%@", args[i])
            
        
    

    return returnString

但是看看它是否对你来说是一个有效的解决方法。

【讨论】:

感谢您的回答,这是一个有趣的解决方法,我会等待一段时间,也许会出现其他解决方案,如果没有,我会除了您的回答,这是我们应该重新发明***的痛苦Kotlin Native 来做这些基本的事情。顺便说一句,也许您知道一些已经具有多平台字符串格式化选项的 KN 库? 这是使用尖端技术支付的费用。认为我们处于 alpha 阶段,只有少数东西处于 beta 阶段。我不知道是否已经有处理字符串格式的 KN 库,但您可以开始搜索 here 和 here。您也可以加入 kotlin slack 频道并在#multiplatform 会议室中提问。 这里有官方答案,也许你也会感兴趣 是的!我见过。这也是我们发现的。该功能缺失,我们制定了解决方法。 W8ing 要添加此功能;)。顺便说一句,我已经赞成你的回答。如果您想更改已接受的答案,请随时这样做。【参考方案2】:

您不能将 Kotlin 可变参数转发给 C 或 Objective-C。 C 可变参数是编译时间。 这不是 Kotlin 特定的限制。您不能通过转发所有参数从另一个可变参数 C 函数调用可变参数 C 函数。

NSString.stringWithFormat(format, args as Any)

这是不正确的。 此行采用 args(这是一个 Array),将其转换为 Any 并作为单个参数传递。

所以这基本上相当于

[NSString stringWithFormat:format, createKotlinArray(/* all arguments here */)]

这并不符合您的预期。

所以KT-42925 无效。 您的问题可能会通过缺少的功能之一来解决:

标准库 (KT-25506) 中的常见 String.format。但这并不容易。 支持动态构建va_list,例如来自 Kotlin Array (KT-42973)。在这种情况下,很容易使用这个变体:https://developer.apple.com/documentation/foundation/nsstring/1407827-initwithformat

【讨论】:

kotlin native 无法导入 khttp

...与python请求的库功能相同的功能)我的build.gradle包含这些字符串:repositoriesmavenCentral()dependenciescompile"org.jetbrai 查看详情

Kotlin/Native 无法导入 io.ktor.network.selector.ActorSelectorManager

】Kotlin/Native无法导入io.ktor.network.selector.ActorSelectorManager【英文标题】:Kotlin/Nativecan\'timportio.ktor.network.selector.ActorSelectorManager【发布时间】:2021-07-1623:41:20【问题描述】:我想使用KTOR在Kotlin/Native中使用TCP套接字,我遵循了tutorial... 查看详情

kotlin.native.concurrent.InvalidMutabilityException:在 Kotlin Multiplatform (iOS) 中使用 ktor 时冻结 <ob

】kotlin.native.concurrent.InvalidMutabilityException:在KotlinMultiplatform(iOS)中使用ktor时冻结<object>的突变尝试【英文标题】:kotlin.native.concurrent.InvalidMutabilityException:mutationattemptoffrozen<object>whenusingktorinKo 查看详情

Kotlin Native (iOS),使用 CValuesRef 和 CCCrypt

】KotlinNative(iOS),使用CValuesRef和CCCrypt【英文标题】:KotlinNative(iOS),usingCValuesRefwithCCCrypt【发布时间】:2021-09-2413:12:39【问题描述】:我正在一个针对iOS的Kotlin多平台项目中研究AES256加密算法。我检查了一些在纯Kotlin中实现此功能... 查看详情

在 iOS/XCode 的内置 .frameworks 中包含 Kotlin/Native KDocs 文档

】在iOS/XCode的内置.frameworks中包含Kotlin/NativeKDocs文档【英文标题】:IncludeKotlin/NativeKDocsdocumentationinbuilt.frameworksforiOS/XCode【发布时间】:2020-07-1919:23:26【问题描述】:我正在为iOS和Android开发一个Kotlin/Native库。当运行./gradlewassemble... 查看详情

如何将 React-Native 代码与 Swift 或 Kotlin 联系起来?我应该用每种语言做啥?

】如何将React-Native代码与Swift或Kotlin联系起来?我应该用每种语言做啥?【英文标题】:HowisitpossibletolinkReact-NativecodewithSwiftorKotlin?WhatshouldIdoineachlanguage?如何将React-Native代码与Swift或Kotlin联系起来?我应该用每种语言做什么?【发... 查看详情

开发ios应用,kotlinnative是不是够格?

...么多的语言要学习,专心研究一门语言就可以了,可是在KotlinConf大会宣布了Kotlin1.2RC版,并宣布Kotlin/Native已支持用于开发iOS应用和Web应用开发。这也将是Kotlin/Native0.4的特性之一。虽然对iOS开发的支持仍处于早期阶段,但确实已... 查看详情

Kotlin Multiplatform Mobile:Ktor - 如何在 Kotlin Native(iOS)中取消活动协程(网络请求、后台工作)?

】KotlinMultiplatformMobile:Ktor-如何在KotlinNative(iOS)中取消活动协程(网络请求、后台工作)?【英文标题】:KotlinMultiplatformMobile:Ktor-howtocancelactivecoroutine(networkrequest,backgroundwork)inKotlinNative(iOS)?【发布时间】:2021-05-0118:32:49【问题... 查看详情

Kotlin Native 项目中 iOS 上的 libPhonenumber(来自 Google)

】KotlinNative项目中iOS上的libPhonenumber(来自Google)【英文标题】:libPhonenumber(fromGoogle)oniOSinaKotlinNativeproject【发布时间】:2020-10-2510:02:55【问题描述】:我一直在努力解决一个问题。我正在使用KotlinMultiplatform(KMP)构建一个跨平台... 查看详情

在 Cocoapod 中导入 Kotlin/Native 框架

】在Cocoapod中导入Kotlin/Native框架【英文标题】:ImportKotlin/NativeframeworkinCocoapod【发布时间】:2018-08-0715:19:12【问题描述】:我正在尝试在私有CocoaPod中添加使用Kotlin/Native构建的供应商框架,但出现错误:我已经使用Kotlin/Native生成... 查看详情

尝试将 Kotlin Native 与 IntelliJ 的基础项目一起使用,但无法编译

】尝试将KotlinNative与IntelliJ的基础项目一起使用,但无法编译【英文标题】:AttemptingtouseKotlinNativewithIntelliJ\'sbaseprojectbutitwon\'tcompile【发布时间】:2019-05-2314:34:50【问题描述】:您好,我正在学习KotlinNative,因此我想从编译和运... 查看详情

Kotlin Native 编译 jar 和框架

】KotlinNative编译jar和框架【英文标题】:KotlinNativecompilejarandframework【发布时间】:2021-03-1009:13:17【问题描述】:我正在为Android和iOS构建一个多平台库。我的gradle文件如下所示:pluginsid\'org.jetbrains.kotlin.multiplatform\'version\'1.4.0\'repo... 查看详情

第9章文件io操作正则表达式与多线程《kotlin项目实战教程》

...,我们可以直接为String类实现一个inc()函数,这个函数把字符串中的每一个字符值加1"abc".inc()//bcd这个扩展函数实现如下funString.inc():String{varresult=""this.map{r 查看详情

如何使用 Kotlin/native 生成​​依赖于另一个的 .framework?

】如何使用Kotlin/native生成​​依赖于另一个的.framework?【英文标题】:Howtogeneratea.frameworkdependingfromanotherwithKotlin/native?【发布时间】:2021-07-2721:18:48【问题描述】:我在KMP和iOS框架方面存在一些依赖问题。这里有一些上下文:... 查看详情

Kotlin Native 如何将 ByteArray 转换为 String?

】KotlinNative如何将ByteArray转换为String?【英文标题】:KotlinNativehowtoconvertByteArraytoString?【发布时间】:2018-09-0304:48:06【问题描述】:我在玩kotlin-nativesamples。我想知道如何从pinnedByteArray获得String。只想在控制台打印出来。【问题... 查看详情

如何在 Kotlin Native 中使用 Http Request 库

】如何在KotlinNative中使用HttpRequest库【英文标题】:HowtouseHttpRequestlibinKotlinNative【发布时间】:2019-06-0221:36:17【问题描述】:我是Kotlin本机的初学者,我的目标是构建一个我们的RestAPI包含它的库,并在iOS和Android上使用它。我知... 查看详情

Kotlin JVM 和 Kotlin Native 有啥区别?

】KotlinJVM和KotlinNative有啥区别?【英文标题】:What\'sthedifferencebetweenKotlinJVMandKotlinNative?KotlinJVM和KotlinNative有什么区别?【发布时间】:2019-08-1919:21:35【问题描述】:所以我知道KotlinNative显然是Native而KotlinJVM不是,而是KotlinJVM和Ko... 查看详情

Kotlin 字符串模板中的格式

】Kotlin字符串模板中的格式【英文标题】:FormatinKotlinstringtemplates【发布时间】:2014-05-2923:01:32【问题描述】:Kotlin有一个很棒的特性,叫做字符串模板。vali=10vals="i=$i"//evaluatesto"i=10"但是模板中可以有任何格式吗?比如我想在kot... 查看详情