diff --git a/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt b/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt index 9723aa2..6e289ef 100644 --- a/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt +++ b/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt @@ -8,6 +8,9 @@ import kotlinx.cinterop.convert @OptIn(kotlinx.cinterop.ExperimentalForeignApi::class) actual class CrashlyticsCallsActual : CrashlyticsCalls { + init { + FIRCheckLinkDependencies() + } override fun logMessage(message: String) { FIRCrashlyticsLog(message) diff --git a/crashlytics/src/nativeInterop/cinterop/crashlytics.def b/crashlytics/src/nativeInterop/cinterop/crashlytics.def index 5391ae4..9cb9892 100644 --- a/crashlytics/src/nativeInterop/cinterop/crashlytics.def +++ b/crashlytics/src/nativeInterop/cinterop/crashlytics.def @@ -7,10 +7,8 @@ language = Objective-C extern void FIRCLSExceptionRecordNSException(NSException *exception) __attribute__((weak)); -void tryFIRCLSExceptionRecordNSException(NSException *exception) { - if (FIRCLSExceptionRecordNSException) { - FIRCLSExceptionRecordNSException(exception); - } else { +void __verifyFIRCLSExceptionRecordNSExceptionExists(void) { + if (!FIRCLSExceptionRecordNSException) { @throw [NSException exceptionWithName:@"FIRFunctionNotFound" reason:@"Function 'FIRCLSExceptionRecordNSException' not available, make sure you're adding the Firebase Crashlytics dependency." @@ -19,6 +17,11 @@ void tryFIRCLSExceptionRecordNSException(NSException *exception) { } } +void tryFIRCLSExceptionRecordNSException(NSException *exception) { + __verifyFIRCLSExceptionRecordNSExceptionExists(); + FIRCLSExceptionRecordNSException(exception); +} + #define LoadClass(name)\ static Class objClass;\ if (!objClass) {\ @@ -52,8 +55,23 @@ void* FIRMethodForSelector(id _Nonnull target, SEL _Nonnull selector) { } } -id FIRExceptionModelWithNameAndReason(NSString* _Nonnull name, NSString* _Nonnull reason) { +Class FIRExceptionModelClass(void) { LoadClass(FIRExceptionModel); + return objClass; +} + +Class FIRStackFrameClass(void) { + LoadClass(FIRStackFrame); + return objClass; +} + +Class FIRCrashlyticsClass(void) { + LoadClass(FIRCrashlytics); + return objClass; +} + +id FIRExceptionModelWithNameAndReason(NSString* _Nonnull name, NSString* _Nonnull reason) { + Class objClass = FIRExceptionModelClass(); SEL selector = NSSelectorFromString(@"exceptionModelWithName:reason:"); id (*exceptionModelWithNameAndReason)(id, SEL, NSString*, NSString*) = FIRMethodForSelector(objClass, selector); return exceptionModelWithNameAndReason(objClass, selector, name, reason); @@ -66,17 +84,21 @@ void FIRExceptionModelSetStackTrace(id exceptionModel, NSArray* _Nonnull sta } id FIRStackFrameWithAddress(NSUInteger address) { - LoadClass(FIRStackFrame); + Class objClass = FIRStackFrameClass(); SEL selector = NSSelectorFromString(@"stackFrameWithAddress:"); id (*stackFrameWithAddress)(id, SEL, NSUInteger) = FIRMethodForSelector(objClass, selector); return stackFrameWithAddress(objClass, selector, address); } -id FIRCrashlyticsInstance(void) { - LoadClass(FIRCrashlytics); +id _Nullable FIRCrashlyticsInstanceOrNull(void) { + Class objClass = FIRCrashlyticsClass(); SEL selector = NSSelectorFromString(@"crashlytics"); id (*crashlytics)(id, SEL) = FIRMethodForSelector(objClass, selector); - id instance = crashlytics(objClass, selector); + return crashlytics(objClass, selector); +} + +id _Nonnull FIRCrashlyticsInstance(void) { + id instance = FIRCrashlyticsInstanceOrNull(); if (instance) { return instance; } else { @@ -120,3 +142,12 @@ void FIRCrashlyticsSetCustomValue(NSString* _Nonnull key, id __nullable value) { void (*setCustomValueForKey)(id, SEL, id __nullable, NSString* _Nonnull) = FIRMethodForSelector(crashlytics, selector); setCustomValueForKey(crashlytics, selector, value, key); } + +void FIRCheckLinkDependencies(void) { + __verifyFIRCLSExceptionRecordNSExceptionExists(); + + // Load classes to verify we have them all + FIRExceptionModelClass(); + FIRStackFrameClass(); + FIRCrashlyticsClass(); +}