iOS - Initialise WebEngage SDK Conditionally with different Accounts Ids - ios

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")
}

Related

MXMetricKit: finishExtendedLaunchMeasurement not work

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];
}
});

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.

How do I prevent Alert when App is on Foreground with Incoming OneSignal Push Notification?

When my app is in the foreground, there is a alert that appears. How do I prevent this from appearing when receiving push notifications?
In your didFinishLaunchingWithOptions method of AppDelegate you have to add kOSSettingsKeyInAppAlerts = NO
[OneSignal initWithLaunchOptions:launchOptions appId:ONESIGNAL_APPID handleNotificationReceived:nil handleNotificationAction:nil
settings:#{kOSSettingsKeyInAppAlerts:#NO}];
For Swift 3.0
// Initialize OngeSignal with Settings for Push Notifications
OneSignal.initWithLaunchOptions(launchOptions, appId: Constants.OneSignalAppID, handleNotificationReceived: nil, handleNotificationAction: {
(result) in
// Do Something with Notification Result
}, settings: [kOSSettingsKeyInFocusDisplayOption : OSNotificationDisplayType.none.rawValue])
By default OneSignal shows notifications as alert dialogs when the app is infocus. To change this pass kOSSettingsKeyInFocusDisplayOption with the value OSNotificationDisplayTypeNotification or OSNotificationDisplayTypeNone to settings on initWithLaunchOptions.
I achieved it this way. Add the following code in your AppDelegate didFinishLaunchingWithOptions
OneSignal.inFocusDisplayType = OSNotificationDisplayType.none
on last line in
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
OneSignal.inFocusDisplayType = OSNotificationDisplayType.none
return true }
we have these 3 options
public enum OSNotificationDisplayType : UInt {
/*Notification is silent, or app is in focus but InAppAlertNotifications are disabled*/
case none
/*Default UIAlertView display*/
case inAppAlert
/*iOS native notification display*/
case notification
}
Here's OneSignal Documentation

Get launchOptions when resuming App

I am able to handle the launchOptions value in the application method (since, obviously, the parameter gets passed to it). What I'm doing is basically receiving an image from a user who imported it by selecting my app in the Share menu:
It works fine if the App hasn't already been launched, but I don't see how I get the input parameters if the App is already running and the application method isn't called.
I tried to find a method that would help me like
applicationWillEnterForeGround(_ application: UIApplication, _ launchOptions: [UIApplicationLaunchOptionsKey: Any]?
but without any success.
I assume it's possible, since you can share images to WhatsApp or Facebook too, even when they've already been launched.
Can someone help me out?
Thanks,
Jan
You should implement the application:openURL:options: method as follows (Swift 2):
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
// Do your stuff and return true if you have handled the URL...
// Else
return false
}
Relevant tutorial in Ray Wenderlich
As of Swift 4.2 the signature is:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
// Do your stuff and return true if you have handled the URL...
// Else
return false
}
I think you're currently watching in the wrong direction. You should refer to Inter-App communication guide, provided by Apple. If generalise this, you simply need this method, that will handle URI link to your app.
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options;

How do you save global arrays in the applicationWillTerminate and reload them in the application function?

So I have been trying to make an app for my Mobile Apps Development class and I need to find a solution to a problem that I'm having when I save a global array called "events".
Here I tried to reload the saved event class in AppDelegate but it didn't change in the main screen view controller:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//Override point for customization after application launch.
//Load the events that were saved when application was terminated
let eventKey = NSUserDefaults.standardUserDefaults()
Global.events = (eventKey.arrayForKey("savedEvents") as? [Event])!
return true
}
Here is the function that is called when someone quits the app:
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
let myEvents = Global.events
NSUserDefaults.standardUserDefaults().setObject(myEvents, forKey: "savedEvents")
NSUserDefaults.standardUserDefaults().synchronize()
}
This might just be an error in the viewcontroller that displays this array but if you see something wrong with the code please let me know.
Two problems:
In iOS, there is no such thing as "someone quits the app", and thus what you're doing is unlikely to work, because applicationWillTerminate is never called. Save when the application is deactivated or backgrounded.
An array of Event cannot magically be saved in user defaults, because Event is not a Property List type. You will need to make Event archivable and archive the array.

Resources