diff --git a/Cargo.lock b/Cargo.lock index 3555c1a3..8a529d68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4430,8 +4430,10 @@ version = "0.1.0" dependencies = [ "android_logger", "byte-unit", + "cocoa", "fern", "log", + "objc", "serde", "serde_json", "serde_repr", diff --git a/plugins/log/Cargo.toml b/plugins/log/Cargo.toml index 864618ea..05a3b058 100644 --- a/plugins/log/Cargo.toml +++ b/plugins/log/Cargo.toml @@ -27,6 +27,8 @@ android_logger = "0.11" [target."cfg(target_os = \"ios\")".dependencies] swift-rs = "1.0.1" +objc = "0.2" +cocoa = "0.24" [features] colored = ["fern/colored"] \ No newline at end of file diff --git a/plugins/log/ios/Sources/LogPlugin.swift b/plugins/log/ios/Sources/LogPlugin.swift index 4ae3621d..954f357e 100644 --- a/plugins/log/ios/Sources/LogPlugin.swift +++ b/plugins/log/ios/Sources/LogPlugin.swift @@ -3,11 +3,11 @@ import Tauri import SwiftRs @_cdecl("tauri_log") -func log(level: Int, message: SRString) { +func log(level: Int, message: NSString) { switch level { - case 1: Logger.debug(message.toString()) - case 2: Logger.info(message.toString()) - case 3: Logger.error(message.toString()) + case 1: Logger.debug(message as String) + case 2: Logger.info(message as String) + case 3: Logger.error(message as String) default: break } } diff --git a/plugins/log/src/lib.rs b/plugins/log/src/lib.rs index 66d534b4..f7e5e25b 100644 --- a/plugins/log/src/lib.rs +++ b/plugins/log/src/lib.rs @@ -23,9 +23,36 @@ use tauri::{ pub use fern; #[cfg(target_os = "ios")] -swift_rs::swift!(fn tauri_log( - level: u8, message: &swift_rs::SRString -)); +mod ios { + use cocoa::base::id; + use objc::*; + + const UTF8_ENCODING: usize = 4; + pub struct NSString(pub id); + + impl NSString { + pub fn new(s: &str) -> Self { + // Safety: objc runtime calls are unsafe + NSString(unsafe { + let ns_string: id = msg_send![class!(NSString), alloc]; + let ns_string: id = msg_send![ns_string, + initWithBytes:s.as_ptr() + length:s.len() + encoding:UTF8_ENCODING]; + + // The thing is allocated in rust, the thing must be set to autorelease in rust to relinquish control + // or it can not be released correctly in OC runtime + let _: () = msg_send![ns_string, autorelease]; + + ns_string + }) + } + } + + swift_rs::swift!(pub fn tauri_log( + level: u8, message: *const std::ffi::c_void + )); +} const DEFAULT_MAX_FILE_SIZE: u128 = 40000; const DEFAULT_ROTATION_STRATEGY: RotationStrategy = RotationStrategy::KeepOne; @@ -268,13 +295,13 @@ impl Builder { fern::Output::call(move |record| { let message = format!("{}", record.args()); unsafe { - tauri_log( + ios::tauri_log( match record.level() { log::Level::Trace | log::Level::Debug => 1, log::Level::Info => 2, log::Level::Warn | log::Level::Error => 3, }, - &message.as_str().into(), + ios::NSString::new(message.as_str()).0 as _, ); } })