ã¯ããã«
ããã«ã¡ã¯ãã¬ã·ãäºæ¥é¨ã§ã¢ã«ãã¤ãä¸ã®æ¾æ¬ (@matsumo0922) ã§ããã¯ãã¯ãããã§ã¯ä»¥åããã¢ãã¤ã«ã¢ããªã±ã¼ã·ã§ã³åãã®ãã®ã³ã°ã©ã¤ãã©ãªã§ãã Puree ãå ¬éãã¦ãã¾ããããä»åæ°ãã Kotlin Multiplatform1 ãç¨ãã KMP çããªãªã¼ã¹ãã¾ãããã¾ãããã®ã©ã¤ãã©ãªã¯æ¢ã« iOSã Android 両æ¹ã®ã¯ãã¯ãããã¢ããªã§åä½ãã¦ãããã¯ãã¯ãããåã® Kotlin Multiplatform å°å ¥äºä¾ã¨ãããã¨ã§ãé£ããã£ãç¹ãªã©ãã©ã¤ãã©ãªã®ç´¹ä»ã¨åããã¦ãç´¹ä»ãã¾ãã
Pureeã¨ã¯
ãµã¼ãã¹ã®ãã°ãåéããéã«ãWeb ã¢ããªã±ã¼ã·ã§ã³ã§ããã°ãµã¼ãã¼å´ã§ãã°ãåéãããã¨ãå¯è½ã§ãããã¢ãã¤ã«ã¢ããªã±ã¼ã·ã§ã³ã¯ç»é¢ã®æä½ã¯ã¢ããªå´ã§ã³ã³ããã¼ã«ããããããã¢ããªããã°ãåéãã¦éä¿¡ããå¿ è¦ãããã¾ããã¢ããªã®æä½ã¯ãã¦ã¼ã¶ã¼ã®ããã¤ã¹ã®ç¶æ ï¼éä¿¡ç°å¢ã黿± æ®éãªã©ï¼ãã¢ããªã®ã©ã¤ããµã¤ã¯ã«ãã¦ã¼ã¶ã¼ã®è¤æ°åã¿ãããªã©æ§ã ãªè¦å ãèæ ®ããã°ãªãããWeb ã¢ããªã±ã¼ã·ã§ã³ã®ãã®ã³ã°ããè¤éã«ãªããããã®ãç¾ç¶ã§ãã
ããã§ãä¸è¨ã®æ§ãªé¢åèãå¦çãå ¨ã¦è¡ã£ã¦ãããã®ããPureeãã¨ããã©ã¤ãã©ãªã§ããPuree ã¯ä»¥ä¸ã®æ©è½ãå ¨ã¦å èµãã¦ããããã®ã³ã°ã¯ Puree ã«ä»»ãã¦ã¢ããªã®ä¸»è¦æ©è½ã®å®è£ ã«æ³¨åãããã¨ãå¯è½ã¨ãªãã¾ãã
- ãã£ã«ã¿ãªã³ã°
- ç¹å®ã®ãã°ã«å¯¾ãã¦å ±éã®ãã©ã¡ã¼ã¿ãä»ä¸ãããããµã³ããªã³ã°ãè¡ããã¨ãå¯è½
- ãããã¡ãªã³ã°
- ç¹å®æéå ã«è¤æ°åéããããã°ã䏿çã«ãããã¡
- éä¿¡ã«å¤±æããå ´åãéä¿¡åã«ã¢ããªã kill ãããå ´åã§ããå é¨ãã¼ã¿ãã¼ã¹ã«èªåä¿å
- ãªãã©ã¤
- ä½ããã®è¦å ã§ãã°ãéä¿¡ãããªãå ´åã§ããèªåçã«ãªãã©ã¤

puree-kmp
ä¸è¨ã®æ§ã«ä¾¿å©ãªã©ã¤ãã©ãªã§ãã Puree ã§ãããå®ã¯æ§ã ãªè¨èªãOSåãã«è¤æ°ã®ã©ã¤ãã©ãªããªãªã¼ã¹ããã¦ãã¾ãã
2014å¹´ã«ãªãªã¼ã¹ãããå ç¥ Puree ã§ãããpuree-android ãç¶ãã¦ãªãªã¼ã¹ããã iOS åã Puree ã§ãããpuree-ios ã2017å¹´ã«ã¯ ReactNative åãã® react-native-puree ãç¿å¹´ã®2018å¹´ã§ã¯ Swift ã§ä¸æ°ããã puree-swift ãAndroid ã®å ¬å¼éçºè¨èªã Kotlin ã¸ã¨ç§»è¡ãã¦ãã°ããçµã£ã2021å¹´ã«ã¯ãJava ãã Kotlin ã«ä¸æ°ããããpuree-kotlin ããªãªã¼ã¹ããã¦ãã¾ãã
techlife.cookpad.com techlife.cookpad.com
ãã®æ§ã«æ§ã ãªç¨®é¡ã¨æ´å²ããã Puree ã§ãããããæ ã«å®éã®éçºç¾å ´ã§ã¯æ§ã ãªå¼å®³ãåå¨ãã¾ãããPuree ã®ããã¾ããªä»æ§ã¯å ¨ã¦ä¼¼éã£ã¦ãã¾ããã詳細é¨åã§ã¯ããããã®ã³ã¼ããã¼ã¹ãã¨ã«ç°ãªã仿§ããããå®éç¨ãã¦ã¿ã㨠iOS 㨠Android ã§ãã°ã®éä¿¡ãããã¿ã¤ãã³ã°ãæ°ãç°ãªãã¨ãã£ãåé¡ã度ã çºçãã¦ãã¾ãããå ãã¦ããã§ã«ã¬ã¬ã·ã¼ã¨ãªã£ã¦ãã Java ã Objective-C ã§æ¸ããã puree-android 㨠puree-ios ã¯ãã¡ããã®ãã¨ãæ¥ã é²åãã¦ããã¢ãã¤ã«ã¢ããªçéã§è¤æ°ã®ã³ã¼ããã¼ã¹ã®ã©ã¤ãã©ãªãä¿å®ãã¦ããã®ã¯ã³ã¹ãçã«ãé£ãããã®ãããã¾ããã
ããã§ãKotlin Multiplatformï¼ä»¥ä¸ KMPï¼ã¨ãããã«ããã©ãããã©ã¼ã æè¡ãç¨ãã¦è¤æ°ã®ã³ã¼ããã¼ã¹ãçµ±åããä¸ã¤ã® Puree ã«ããã¨ããç®æ¨ãæ²ãã¦ä½ãããã®ããpuree-kmpãã§ãã
ç¹å¾´
puree-kmp 㯠puree-kotlin / puree-swift ã®è¨è¨ææ³ãè¸è¥²ãã¤ã¤ãKMP åã«éãã¦ä»¥ä¸ã®æ§ãªå¤æ´ãè¡ãªã£ã¦ãã¾ãã
åãã¼ã¹ã® Filter / Output
puree-swift ã§ã¯ã¿ã°ãã¿ã¼ã³ãç¨ãã¦æååãã¼ã¹ã® Filter & Output ã®è¨å®ãè¡ã£ã¦ãã¾ããããããããç¬ç«ãã¦ãã¿ã¼ã³ãè¨è¨ããã®ãé£ãããããå®å ¨ãªåãããã³ã°æ¹å¼ã«ç§»è¡ãã¹ãã¨ããè°è«ã社å ã§ã度ã èµ·ãã£ã¦ãã¾ãããæºãæãã¦åãã¼ã¹ã«ç§»è¡ã§ãã
ããã©ã«ãã® Filter / Output ã®ãµãã¼ã
åãã¼ã¹ã«ç§»è¡ãããã¨ã«ãããå ¨ã¦ã®åã«å¯¾ãé©å¿ãã Filter 㨠Output ãç»é²ããå¿ è¦ãåºã¦ãã¾ãããã¯ãã¯ãããã§è¨é²ãã¦ãããã°ã®æ°ã¯è¨å¤§ã§ããããããã®å ¨ã¦ã Puree ã«ç»é²ãã¦ããã®ã¯å¹ççã§ç¡ãã¨å¤æããããã©ã«ãã® Filter 㨠Output ããµãã¼ãããæ§ã«å¤æ´ãã¾ããã
Full Kotlin
ããã¯è¨èªã¨ãã¦ã® Java ã使ç¨ãã¦ããªãã¨ããæå³ã§ã¯ãªããä¾åãã¦ããã©ã¤ãã©ãªãå«ãã¦å ¨ã¦ Kotlin ã§æ¸ããã¦ããã¨ããæå³ã§ããKMP ãªã®ã§å½ããåã§ã¯ããã¾ãããããã«ããã¬ã¬ã·ã¼ãªã©ã¤ãã©ãªã¸ã®ä¾åã䏿ãããã¨ãã§ãã¾ãããAndroidã§ã¯ãã°ã®ã·ãªã¢ã©ã¤ãºã«ã¯ kotlinx.serializationããã¼ã¿ã®æ°¸ç¶åã«ã¯ androidx.room ãæ¡ç¨ãããªã©ãç©æ¥µçã«éçºãè¡ããã¦ããå ¬å¼ã®ã©ã¤ãã©ãªãå¤ç¨ãã¦ãããããä¿å®æ§ã¯ãã¡ããã©ã¤ãã©ãªã¨ãã¦ã®å¯¿å½ã伸ã°ããã¨ãã§ãã¦ããã¯ãã§ãã
Swift Friendly
KMP ã®ã©ã¤ãã©ãªã¯åã KMP ããã¸ã§ã¯ãããåç §ããããã¨ãåæã«ãã¦ãããã®ãå¤ããSwift ããåç §ããããã¨ããã¾ãèæ ®ããã¦ãã¾ããããã㯠KMP ã¨ãã¦ã®ä»æ§ãå°ã絡ãã§ãã¾ãããKMP 㯠Kotlin â LLVM â Objective-C â Swift ã¨ããæé ãè¸ãã§ Swift ããåç §ããããããããããã®è¨èªæ¯ã®å·®ç°ãç´¯ç©ãã¦ãã¾ãã¾ããä¾ãã°ãKotlin ã® null å®å ¨ã Objective-C ãéããã¨ã«ãã£ã¦ææ§ã«ãªã£ãããKotlin ã® interface 㯠Objective-C ã® protocol ã«å¤æããã¾ãããObjective-C ã® protocol 㯠Swift ã® struct ã§æºæ ã§ããªãã¨è¨ã£ãåé¡çãæèã㦠Swift Friendly ã«æ¸ããªããã° Swift ã§ã¯å©ç¨ãã¥ããã©ã¤ãã©ãªã¨ãªã£ã¦ãã¾ãã¾ããpuree-kmp ã§ã¯åºç¤è¨è¨ãã§ããã ãå ±éã«ãã¤ã¤ãSwift åãåºæã®ã³ã¼ããç¨æããSwift ããã§ãå©ç¨ããããã©ã¤ãã©ãªã¨ãªããã¨ãå¿ããã¦ãã¾ãã
åãã©ãããã©ã¼ã ã¸ã®æ¡å¼µæ§
ç¾ç¶ puree-kmp ããµãã¼ããã¦ãããã©ãããã©ã¼ã 㯠Android 㨠iOS ã ãã§ãããã»ã¼å ¨ã¦ã®ã³ã¼ããå ±éã¢ã¸ã¥ã¼ã«ã§è¨è¿°ãã¦ãããããå¥ãã©ãããã©ã¼ã ã¸ã®æ¡å¼µã容æã«è¡ããè¨è¨ã¨ãªã£ã¦ãã¾ããå°æ¥çã«ã¯ JVMãDesktopãWebAssembly ã¸å±éãã¦ãããã°ã¨èãã¦ãã¾ãã
ä½¿ãæ¹
åè¿°ã®éããè¨è¨ã¯ä»¥åã® Puree ããå¼ãç¶ãã§ããã®ã§ãç¾å¨ puree-kotlin ã¾ã㯠puree-swift ãå©ç¨ãã¦ããå ´åã¹ã ã¼ãºã«ç§»è¡ãããã¨ãã§ãã¾ããå®è£ ä¾ã¨ãã¦ã以ä¸ã®ãã㪠ClickLog ãéä¿¡ããä¾ãèãã¦ã¿ã¾ãã
Puree ãæ±ãã«ã¯ä»¥ä¸ã®4ã¹ããããå¿ è¦ã§ãã
- ä¾åã®è¿½å
- ãã°ãå®ç¾©
- PureeFilter 㨠PureeOutput ãå®è£
- ãã°ã®åããã¼ã¹ã«ã©ã® PureeFilter 㨠PureeOutput ã使ããç»é²ãã
ãã詳ããä½¿ãæ¹ã¯ README ãã覧ãã ããã
å°å ¥
Android ã§ã¯ Maven CentralãiOS ã§ã¯ Swift Package manager ããå°å ¥ãããã¨ãã§ãã¾ãã
dependencies {
implementation("com.cookpad.puree:puree-kmp:$latestVersion")
}
ãã°å®ç¾©
éä¿¡ãããã°ãå®ç¾©ãã¾ããPureeLog ãç¶æ¿ / æºæ ãããã¨ã§ Puree ã§æ±ãããã°ã¯ã©ã¹ã¨ãªãã¾ããAndroid ã§ã¯ããã©ã«ãã§ kotlinx.serialization ã使ç¨ãã¦ããã®ã§ã@Serializable ã¢ããã¼ã·ã§ã³ãã¤ããã®ãå¿ããªãã§ãã ããããªããkotlinx.serialization ã使ç¨ããå ´åã®æ³¨æã¨ãã¦ãdata object ã§ãã°ãå®ç¾©ãã¦ãã¾ãã¨ããããã£ãã·ãªã¢ã©ã¤ãºããã¾ããã®ã§ã注æãã ããï¼ä¸æï¼ã
@Serializable data class ClickLog( @SerialName("button_name") val buttonName: String, ) : PureeLog
Swift ã§ãã°ã¯ã©ã¹ãå®ç¾©ããå ´å㯠KMP ã®ä»æ§ä¸ struct ã¯ä½¿ãã¾ããã®ã§ãclass ã§å®è£ ãã¦ãã ãããã¾ããå¾è¿°ãã¾ãã Swift ã§æ¸ãããã¯ã©ã¹ã«å¯¾ãã¦ã¯ãã¡ãã kotlinx.serialization ã使ããã¨ãã§ããªãã®ã§ãèªåã®ã·ãªã¢ã©ã¤ãºæ©æ§ãå®è£ ããå¿ è¦ãããã¾ãã以ä¸ã®ä¾ã§ã¯ Encodable ãç¨ãã¦ãã¾ãããclass â Json ã®å¤æãã§ããã°ãªãã§ãè¯ãã§ããããã¸ã§ã¯ãã«åããã¦å®è£ ãã¦ãã ããã
class ClickLog: PureeLog, Encodable { let buttonName: String init(buttonName: String) { self.buttonName = buttonName } }
PureeFilter ã®å®è£
PureeFilter ãå®è£ ãã¦ãã£ã«ã¿ãªã³ã°æ©æ§ã追å ãã¾ããããã§ç¹å®ã®ãã°ãå¼¾ããããä»»æã®ãã¤ãã¼ãã追å ã§è¼ãããã¨ãå¯è½ã§ããã¯ãã¯ãããã¢ããªã§ã¯ã¦ã¼ã¶ã¼ã®æ å ±ãæéãªã©ã追å ãã¦ãã¾ãã
class AddTimeFilter : PureeFilter { override fun applyFilter(log: JsonObject): JsonObject? { buildJsonObject { put("time", System.currentTimeMillis()) put("log_id", UUID.randomUUID().toString()) }.also { return JsonObject(log + it) } } }
class AddTimeFilter: PureeFilter { func applyFilter(log: String) -> String? { guard var json = parseJSON(log) else { return log } let dateFormatter = ISO8601DateFormatter() json["time"] = dateFormatter.string(from: Date()) json["log_id"] = UUID().uuidString return stringifyJSON(json) ?? log } }
PureeOutput ã®å®è£
PureeOutput ã§ã¯ãã°ã®éä¿¡æ©æ§ãå®è£
ãã¾ããéä¿¡æ¹æ³ã«ã¯äºç¨®é¡ããããã°ãçºçãããç¬æã«éä¿¡ãè¡ã PureeOutput ã¨ãä¸å®æéãã°ããããã¡ãªã³ã°ãã¦ã¾ã¨ãã¦éä¿¡ãè¡ã PureeBufferedOutput ãããã¾ãããã¼ãºã«åããã¦ä½¿ãåãã¦ãã ããã以ä¸ã®ä¾ã§ã¯åã«æ¨æºåºåãè¡ãã ãã§ãããæ¬æ¥ã§ããã°åã
ã®ãã°åºç¤ã¸éä¿¡ãããããã¯ã¼ã¯éä¿¡ãç¨ããå®è£
ã«ãªãã¯ãã§ãã
class LogcatOutput : PureeOutput { override fun emit(log: JsonObject) { Log.d("Puree", log.toString()) } }
class OSLogOutput: PureeOutput { func emit(log: String) { os_log("Puree: %s", log: osLogger, type: .debug, log) } }

PureeBufferedOutput ã§ã¯ãã°ã®éä¿¡ã¿ã¤ãã³ã°ãã«ã¹ã¿ãã¤ãºãããã¨ã§ããä¾ãã°ãããã¡ããæéãæå®ãããããããã¡ããããã°ã®æ°ãæå®ããããããã¨ãå¯è½ã§ãã以ä¸ã®ä¾ã§ã¯ flushInterval ãç¨ãã¦ãããã¡ããæéãæå®ãã¦ãã¾ãããã®é¢æ°ã¯éåæã§å¼ã³åºããããããéä¿¡ã«æåã¾ãã¯å¤±æããå ´åã®ã³ã¼ã«ããã¯ãå¼ã³åºãå¿
è¦ããããã¨ã«æ³¨æãã¦ãã ãããç¹ã«å¤±æããå ´åã¯ãPuree ãèªåçã«ãªãã©ã¤ã¸ã¨ãã³ããªã³ã°ãã¦ããã¾ãã
class LogcatBufferedOutput(uniqueId: String) : PureeBufferedOutput(uniqueId) { init { flushInterval = 5.seconds } override fun emit(logs: List<JsonObject>, onSuccess: () -> Unit, onFailed: (Throwable) -> Unit) { // Process logs in batch Log.d("Puree", "Logs: $logs") onSuccess() } }
class OSLogBufferedOutput: PureeBufferedOutput { override init (uniqueId: String) { super.init(uniqueId: uniqueId) setFlushInterval(flushIntervalMillis: 5000) } override func emit(logs: [String], onSuccess: @escaping () -> Void, onFailed: @escaping (KotlinThrowable) -> Void) { os_log("Puree Buffered Logs: %s", log: osLogger, type: .debug, log) onSuccess() } }

Puree ãæ§æ
ä»ã¾ã§å®è£
ããã¯ã©ã¹ãã¡ãç¨ã㦠Puree ãæ§æãã¦ããã¾ãããã°ã®å㨠PureeFilterãPureeOutput ãç¨ãã¦ã©ã®åã«ã©ã® Filter / Output ãé©ç¨ããã®ããæ±ºãã¦ããã¾ãããªããdefaultOutput() 㨠defaultFilter() ã¯å
¨ã¦ã®ãã°ã«å¯¾ãé©ç¨ããã¾ãã
val logger = Puree( logStore = DefaultPureeLogStore("puree.db"), ) .output(LogcatBufferedOutput("buffered"), ClickLog::class, MenuLog::class) .defaultOutput(LogcatOutput()) .defaultFilter(AddTimeFilter()) .build()
Swift ã§æ¸ãå ´åã¯åè¿°ã®éãèªåã§ã·ãªã¢ã©ã¤ãºæ©æ§ãæ¸ãå¿ è¦ãããã¾ãã
private class DefaultPureeLogSerializer: PureeLogSerializer { func serialize(log: any PureeLog, platformClass: PlatformClass<any PureeLog>) -> String { return (log as? PureeLog & Encodable)?.encode() ?? "" } } private let logger: PureeLogger = { let logStore = PlatformDefaultPureeLogStore(dbName: "puree.db") let logSerializer = DefaultPureeLogSerializer() return Puree(logStore: logStore, logSerializer: logSerializer) .output(output: OSLogBufferedOutput(uniqueId: "buffered"), logTypes: [ClickLog.self, MenuLog.self]) .defaultOutput(outputs: [OSLogOutput()].toKotlinArray()) .defaultFilter(filters: [AddTimeFilter()].toKotlinArray()) .build() }()
éä¿¡
ããã¾ã§ã»ããã¢ããããã°æ®ãã¯ç°¡åã§ãããã°ã¯ã©ã¹ã Puree ã«æ¸¡ãã¦éä¿¡ããã ãã§ãã
logger?.send(ClickLog("button1"))
ã©ã¤ããµã¤ã¯ã«
ã¢ããªã®ã©ã¤ããµã¤ã¯ã«ã«å¿ãã¦ãã°ã®éä¿¡ã¿ã¤ãã³ã°ãã³ã³ããã¼ã«ããã«ã¯ PureeLogger.resume()ãPureeLogger.pause() ã使ç¨ãã¾ãããªããAndroid ã«ããã¦ã¯ ProcessLifecycleOwner ãç¨ã㦠Puree ãèªåã§éä¿¡ã¿ã¤ãã³ã°ãã³ã³ããã¼ã«ãããããæåã§ã®æä½ã¯ç¹ã«ä¸è¦ã§ãã
iOS ã§ã UIApplicationDidBecomeActiveNotification çã¦ããã¼ãµã«ã«ã¢ããªã®ç¶æ
ãéç¥ãã¦ãããä»çµã¿ã¯åå¨ãã¾ãããããã㯠CREATE â START ã¨ãã£ãç¶æ
é·ç§»ã®é£ç¶æ§ãä¿è¨¼ããã¦ããªãä¸ã«ãçä¿¡ã Siri ã®å²ãè¾¼ã¿ã¨ãã£ãã¦ã¼ã¶ã¼ä¸»ä½ã§ãªãé·ç§»ã§ã¯çºç«ããªããããProcessLifecycleOwner ã»ã©å
æ¬çãªã©ã¤ããµã¤ã¯ã«ç®¡çã¯ã§ããªãã¨å¤æããiOS ã§ã®éä¿¡ã¿ã¤ãã³ã°ã®ã³ã³ããã¼ã«ã¯å®è£
ããã¦ãã¾ããã
é£ããã£ãç¹
ä¸è¬çã« KMP ã©ã¤ãã©ãªã¯ KMP ããã¸ã§ã¯ãããå¼ã³åºããããã¨ãæ³å®ãã¦è¨è¨ãããã¨æãã¾ãããã¯ãã¯ãããã¢ããªã¯ä¾ç¶ã¨ã㦠KMP ã§ã¯ãªããããããããã®ãã¤ãã£ãã³ã¼ãããå¼ã³åºãããåæã§ã³ã¼ããæ¸ãå¿ è¦ãããã¾ããããã®éç¨ã§é£ããã£ãç¹ãèºããç¹ãã話ããã¾ãã
åã®åãæ¸¡ã
Kotlin â Swift ã¸ã¯å®¹æã«åãæ¸¡ããã¨ãå¯è½ã§ãããä»ååãçµãã ã®ã¯ Swift â Kotlin ã¸ã¨åãåãæ¸¡ããã¨ã§ãããKotlin ã§ã¯å㯠KClass ã¨ãã¦æ±ããã¨ãã§ãã¾ãããSwift ã®å ´å㯠KMP ã®ä»æ§ã¨ãã¦ã¤ã³ã¿ã¼ãã§ã¼ã¹ä¸ã®ã¸ã§ããªã¯ã¹åãã©ã¡ã¼ã¿ã¯ ObjC ã«å¤æãããæç¹ã§æ¶å¤±ãã¦ãã¾ããããSwift â Kotlin ã¸ã¨åãæ¸¡ããéãObjCClass ã¨ããåãããªããªã£ã¦ãã¾ãã¾ããããã§åæ
å ±ã String ã«å¤æãã¦æã¤ expect class ãå®è£
ããå
±éã³ã¼ãã§ã¯ãããåãåããã¨ã§ãã°ã®èå¥ãè¡ã£ã¦ãã¾ãã
/** * Platform-specific class wrapper for PureeLog types. * * This class provides a common interface for platform-specific class references, * allowing the logging system to work with class information in a platform-independent way. * Each platform (Android, iOS) implements this class differently to handle its specific * class reference mechanism. * * @param T The type of PureeLog this class represents * @property simpleName The simple name of the class, used for log type identification */ expect class PlatformClass<T : PureeLog> { val simpleName: String } // androidMain actual class PlatformClass<T : PureeLog>(val kClass: KClass<T>) { actual val simpleName: String get() = kClass.simpleName.orEmpty() } // iosMain actual class PlatformClass<T : PureeLog>(private val clazz: ObjCClass) { actual val simpleName: String get() = NSStringFromClass(clazz) }
ä¾åãã¦ãã KMP ã©ã¤ãã©ãªã Swift Friendly ã§ã¯ãªã
åè¿°ã®éããKMP ã©ã¤ãã©ãªã¯ KMP ããã¸ã§ã¯ãããåç
§ããããã¨ãåæã¨ãã¦ãããã¨ãå¤ããããã¯å
¬å¼ã® Jetbrains ã Google ã® KMP ã©ã¤ãã©ãªã§ãä¾å¤ã§ã¯ããã¾ãããä¾ãã°ãPureeBufferedOutput ã§ã¯ãããã¡ããæéãè¨å®ããããã« kotlin.time ã® Duration ãç¨ãã¦ãã¾ãããPureeOutput ã®å®è£
ãã®ã»ã¯ã·ã§ã³ã§ã¯å®è£
ä¾ã¨ã㦠Kotlin / Swift ã®ä¸¡æ¹ã§ BufferedOutput ãå®è£
ãã¦ãã¾ãããKotlin ã§ã¯ flushInterval = 5.seconds 㨠Duration ãç¨ãã¦æ¸ãã¦ããã®ã«å¯¾ããSwift ã§ã¯ setter ã¡ã½ãããå¼ã³åºãã¦ãã¾ãããã㯠Duration ã Swift ããè¦ãéã« Int64ããããåããç§åä½ã¨ããæå³ãåãããªãå½¢ã«å¤æãããããã§ãããããã£ãåé¡ããããpuree-kmp ã§ã¯ã§ããã ãä¾åãã¦ãã KMP ã©ã¤ãã©ãªã Swift å´ã«å
¬éããªãããã©ãããããªã©ãã¦å¯¾çãè¡ãã¾ããã
SwiftUI Preview ãåããªã
ã©ã¤ãã©ãªãéçãã¬ã¼ã ã¯ã¼ã¯ã¨ãã¦ä½æãã¦ããã¨ãiOS ããã¸ã§ã¯ãå´ã§ SwiftUI Preview ãåä½ããªããªãåé¡ãããããã§ã 2ã Xcode16 ããå°å
¥ãããæ°ãã Preview ã¨ã³ã¸ã³ã¨ã®ç¸æ§ãæªããããã§ããã詳細ãªåå ã¯ä¸æã§ããã©ã¤ãã©ãªãåçãã¬ã¼ã ã¯ã¼ã¯ã¸ã¨å¤æ´ãããã¨ã§ç¡äº Preview ãåä½ããããã«ãªãã¾ããããªããBitcode ãç¨ãã¦ããå ´åãåçãã¬ã¼ã ã¯ã¼ã¯ã ã¨æ¬çªç°å¢ã§ã¯ã©ãã·ã¥çãçºçãã¦ã dSYM ããã¦ã³ãã¼ãã§ããªãã¨ããåé¡ãå¥éåå¨ãã¾ãã®ã§ã注æãã ãã 3ã

ã¾ã¨ã
ã¯ãã¯ãããåã® KMP éçºäºä¾ã¨ãããã¨ããããç¥è¦ãå°ãªãç¶æ ã§ã®ã¹ã¿ã¼ãã ã£ãã®ã§æ§ã ãªåé¡ãèºããããã¾ãããããªãã¨ãå½åã®ç®æ¨ã§ãã Puree ã®ã³ã¼ããã¼ã¹ãä¸ã¤ã«ããã¨ããç®æ¨ãéæãããã¨ãã§ãã¾ãããä»åã®ç¥è¦ãä»å¾ã®éçºã«æ´»ããã¦ãããã° 4 ã¨æãã¾ãã
- KMPã¨ã¯↩
- Dynamic Framework ã 㨠SwiftUI Preview ãè¡ããªãåé¡↩
- Dynamic Framework ã 㨠dSYM ããã¦ã³ãã¼ãã§ããªãåé¡↩
-
ãã°ã¨ããã°ãã¯ãã¯ãããã§ã¯ Markdown ãããã°ã¯ã©ã¹ãçæãã daifuku ã¨ãã OSS ãåå¨ãã¾ãããã® KMP çã¨ãªã
daifuku-kmpãéçºããå ±éã³ã¼ãã«ãã°ã¯ã©ã¹ãçæã§ããã°ãã°å¨ããå ¨ã¦ KMP ã§è¡ããã¨ãã§ããåãã©ãããã©ã¼ã ã«ãããã°ã®å·®ç°ãå®å ¨ã«ç¡ãããã¨ãã§ãããªãã¨ï¼å人çã«ï¼èãã¦ãã¾ãã↩