MXMetricKit: finishExtendedLaunchMeasurement not work - ios

Xcode throw an error when i call the api finishExtendedLaunchMeasurement :
[General] Couldn't find persisted ALM/FrontBoard launch signpost id when finishing an ext launch task.
Error Domain=MXErrorDomain Code=5 "Internal failures happened inside of MetricKit." UserInfo={NSLocalizedDescription=Internal failures happened inside of MetricKit.}
The following code:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// create window
MXMetricManager.shared.add(self)
do {
let task_id = MXLaunchTaskID("1234.zmmm")
try MXMetricManager.extendLaunchMeasurement(forTaskID: task_id)
print("some task perform")
try MXMetricManager.finishExtendedLaunchMeasurement(forTaskID: task_id)
} catch {
print(error)
}
return true
}
how i can fix this problem?

you should not call finishExtendedLaunchMeasurement here
because the app is not launch completely there.
just do it like this, or any other time you want, such as the first screen showed
dispatch_async(dispatch_get_main_queue(), ^{
if (#available(iOS 16.0, *)) {
[[MetricsManager shared] finishLaunchMeasurement];
}
});

Related

iOS - Initialise WebEngage SDK Conditionally with different Accounts Ids

I am in need of Initialising WebEngage SDK based on some conditions.
if condition {
//initialise with `X` Account ID
} else {
//initialise with `Y` Account ID
}
But as per WebEnage-Documentation there is no method for initialising SDK with accountId.
we just call below code in our AppDelegate's didFinishLaunchingWithOptions method.
WebEngage.sharedInstance().application(application,
didFinishLaunchingWithOptions: launchOptions)
and it initialise the SDK by reading account id from info.plist file.
I tried updating Info.plist at run time but that didn't work.
I am looking for the right approach to do it.
In WebEngage v6.0.0 a new initialising method is introduced that can have licenseCode as parameter.
func application(_ application: UIApplication?, didFinishLaunchingWithOptions launchOptions: [AnyHashable : Any]?, notificationDelegate: WEGInAppNotificationProtocol?, autoRegister apnRegister: Bool, setLicenseCode licenseCode: String?) -> Bool
I initialises SDK with help of above method in AppDelegate's didFinishLaunchingWithOptions method.
if staging {
WebEngage.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions, setLicenseCode: "xyz")
} else {
WebEngage.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions, setLicenseCode: "abc")
}

Picture-in-picture in iOS fails with saying that the activationState is something other than foregroundActive but it is actually foregroundActive

I am implemeting Picture-in-picture on iOS. I added the background mode capability. When I call isPictureInPicturePossible, it returns false with error:
pictureInPictureController failedToStartPictureInPictureWithError Error Domain=AVKitErrorDomain Code=-1001 "Failed to start picture in picture." UserInfo={NSLocalizedDescription=Failed to start picture in picture., NSLocalizedFailureReason=The UIScene for the content source has an activation state other than UISceneActivationStateForegroundActive, which is not allowed.}
But I when I log the activationState, I can see that it is actually foregroundActive. Any idea what could be the reason?
(before that isPictureInPictureActive returns true, isPictureInPictureSuspended returns false, isPictureInPictureActive returns false.)
It is a little difficult to give an opinion without access to the code and without knowing the versions.
My suggestions:
Check if the app is really in the foreground. You can verify this by looking at the activationState of the UIScene for the content source. If it's not foregroundActive, you can't start the image in the image. If you are using a UISceneDelegate, you can check the activation state of the scene in the sceneWillEnterForeground: method. If using an AppDelegate, you can check the activation state of the scene in the applicationDidBecomeActive: method.
If you use using a UISceneDelegate instead of a AppDelegate. Change it to AppDelegate.
Set the sceneActivationState to foregroundActive in the AppDelegate.swift file:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 13.0, *) {
let scene = UIApplication.shared.connectedScenes.first
if let sceneDelegate = scene?.delegate as? SceneDelegate {
sceneDelegate.window?.windowScene?.activationState = .foregroundActive
}
}
return true
}
If no option to validate. We will give you more information about the problem.

Can't register for Sendbird push notifications in Swift

I have an iOS app in which I am using Sendbird successfully. Nevertheless, the functionality of receiving notifications when the app is running in background does not work. In fact, when I try to register the user for these notifications in the AppSelegate.swift file, I get the error 800101 ERR_CONNECTION_REQUIRED, what suggests I am not connecting correctly to the Sendbird server. However, I have checked that the connection is established without giving errors as soon as the app launches and before trying to register for those notifications.
This is the code for establishing the connection:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
SBDMain.initWithApplicationId(Constants.SENDBIRD_APP_ID, useCaching: false) {
} completionHandler: { error in
print(error)
}
...
}
This is my code for trying to register:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
SBDMain.registerDevicePushToken(deviceToken, unique: true, completionHandler: { (status, error) in
if error == nil {
if status == SBDPushTokenRegistrationStatus.pending {
return
}
else {
print("Successfully registered")
}
}
else {
print(error)
}
})
}
As I said, I have made sure the sendbird application is initialized before the registration, but for some reason, when trying to register for the push notifications I get the "connection required" error. The rest of the Sendbird functionalities work fine, so I guess the connection is well established. The notifications work fine on Android using the same data.
Disclaimer: I am a Sendbird employee.
Hi Pepito,
I'm unsure specifically what version you're on however it looks like you may not be calling the actual connect method prior to trying to register the token.
There is a two step process when creating a connection. The first is initializing the SDK with your Application ID. The second is actually calling the connect method with the userId and accessToken(If you're using them).
// Initialize a SBDMain instance to use APIs in the client app.
SBDMain.initWithApplicationId(APP_ID, useCaching: false) {
} completionHandler: { error in
}
// The USER_ID below should be unique to your Sendbird application.
SBDMain.connect(withUserId: USER_ID, completionHandler: { (user, error) in
guard error == nil else {
// Handle error.
}
// The user is connected to Sendbird server.
...
})
If you're still having trouble after this, I suggest you reach out on our community forums so we can acquire more information from you. https://community.sendbird.com

Firebase Analytics.logEvent() doesn't work, but native event are ok

First of all, here are my steps:
Pod Firebase/Analytics 7.5.0 : OK
FirebaseApp.configure() in app.delegate : OK
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
guard let window = self.window else { return false }
FirebaseConfiguration.shared.setLoggerLevel(.max)
FirebaseApp.configure()
Analytics.setAnalyticsCollectionEnabled(true)
Google plist : OK ( tested with anther blank application it does work )
No env var stored
Debug mode : OK
I do have firebase's native event as Screen view, session_start etc :
[Firebase/Analytics][I-ACS023072] Event logged. Event name, event params: screen_view (_vs)
but as soon as I send myself an event, nothing in DebugViews ( Xcode + Firebase console )
Analytics.logEvent("event", parameters: nil)
What did I miss, configuration, conflicts between some pods ?
Regards

Detect app crashed during load / last time it was run?

I would like for my app to reset to standard settings if it crashed during startup. Preferably also if it crashed last time it was run.
EDIT: Crittercism has a crittercismDidCrashOnLastLoad method, but it only handles the case of crashing during load. It didn't work properly in the version of the library I used, but this has since been fixed.
Suggestions?
Make 2 functions in your AppDelegate.m file:
void HandleException(NSException *exception) {
NSLog(#"App crashing with exception: %#", exception);
//Save somewhere that your app has crashed.
}
void HandleSignal(int signal) {
NSLog(#"We received a signal: %d", signal);
//Save somewhere that your app has crashed.
}
Then in your -(BOOL)application:didFinishLaunchingWithOptions before anything else put:
NSSetUncaughtExceptionHandler(&HandleException);
struct sigaction signalAction;
memset(&signalAction, 0, sizeof(signalAction));
signalAction.sa_handler = &HandleSignal;
sigaction(SIGABRT, &signalAction, NULL);
sigaction(SIGILL, &signalAction, NULL);
sigaction(SIGBUS, &signalAction, NULL);
Using Crashlytics you then can set CrashlyticsDelegate to detect a crash on Swift or ObjC code.
import Fabric
import Crashlytics
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
Crashlytics.sharedInstance().delegate = self
Fabric.with([Crashlytics.self])
return true
}
//MARK: - CrashlyticsDelegate
func crashlyticsDidDetectReport(forLastExecution report: CLSReport, completionHandler: #escaping (Bool) -> Void)
{
completionHandler(true)
}
From Crashlytics docs
Your delegate must invoke the completionHandler, but does not need to
do so synchronously, or even on the main thread. Invoking
completionHandler with NO will cause the detected report to be deleted
and not submitted to Crashlytics. This is useful for implementing
permission prompts, or other more-complex forms of logic around
submitting crashes.
Make certain that the delegate is setup before starting Crashlytics
with startWithAPIKey:… or via [Fabric with:…]. Failure to do will
result in missing any delegate callbacks that occur synchronously
during start.

Resources