Onesignal push notification only accept English language ones in Swift 3 - ios

I have 2 segment in onesignal panel bir EN another FR but in my app have language change and people can change app language everytime in app inside , when I send push from one signal I send by segments but i want to add appdelegate inside language section if user language is English only must be alert English pushes , if user language France only must be alert France pushes.
In my app side language selection string is
let appcurrentlanguage = prefs.value(forKey: "lang") as! String
How can I do it ?
My codes under below
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
//HERE APP LANGUAGE
let appcurrentlanguage = prefs.value(forKey: "lang") as! String
GMSServices.provideAPIKey("xxx")
OneSignal.initWithLaunchOptions(launchOptions, appId: "xxx") { (result) in
let payload = result?.notification.payload
if let additionalData = payload?.additionalData, let actionSelected = additionalData["comes"] as? String {
if actionSelected == "1" {
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = initialViewControlleripad
self.window?.makeKeyAndVisible()
}else if actionSelected == "2" {
if let newsID = additionalData["id"] as? String {
prefs.setValue(newsID, forKeyPath: "gelenID")
prefs.synchronize()
}
if let newsType = additionalData["type"] as? String {
prefs.setValue(newsType, forKeyPath: "newsType")
prefs.synchronize()
}
}
}
}
sleep(2)
return true
}

Related

Once i Login why i am not getting HomeViewController as Rootviewcontroller in Swift?

In appdelegate i am getting UserId.. means i am login but when i run second time i am not getting homeviewcontroller as rootviewcontroller why? still it shows phonenumviewcontroller
navigationcontroller -> phonenumviewcontroller -> registrationiewcontroller -> homeviewcontroller
In storyboard navigationcontroller is initialviewcontroller
In registrationviewcontroller i am getting userId which i have saved in keychain.
I dont have signout button so i have written code like below in registrationiewcontroller
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String:AnyObject]
print("terms and condition JSON \(json)")
let jsonObj: String = json["Success"] as? String ?? ""
if jsonObj == "true" {
let userID: String=jsonObj?["userId"] as? String ?? ""
DispatchQueue.main.async {
KeychainWrapper.standard.set(userID, forKey: "USERID")
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController;
UserDefaults.standard.set("NoLogout", forKey:"Signout")
self.navigationController?.pushViewController(viewController, animated: true);
}
}
}
no signout button so added this code in registrationviewcontroller
UserDefaults.standard.set("NoLogout", forKey:"Signout")
this code in appdelegate: getting userId but still homeviewcontroller is not coming as rootviewcontroller, only phonenumviewcontroller is coming why?
var savedUserId: String?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
savedUserId = KeychainWrapper.standard.string(forKey: "USERID")
KeychainWrapper.standard.set(savedUserId ?? "", forKey: "PersonalID")
print("appdelegate userid \(savedUserId)")
logOutString = UserDefaults.standard.string(forKey: "Signout") as NSString? ?? "" as NSString
if logOutString.isEqual(to: "NoLogout") {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyBoard = UIStoryboard.init(name: "Main", bundle: nil)
let viewcontroller = storyBoard.instantiateViewController(withIdentifier: "HomeViewController")
let navigationController = UINavigationController(rootViewController: viewcontroller)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
}
else {
}
return true
}
once registration is completed i need rootviewcontroller as homeviewcontroller... how to get that, please help me with code
From whatever I've gathered, here's what you need to do:
In AppDelegate:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let isUserLoggedIn = UserDefaults.standard.bool(forKey: "isUserLoggedIn") // Give you own check to see if user is logged in
window = UIWindow()
window?.makeKeyAndVisible()
let viewController = isUserLoggedIn ? MainViewController() : LoginViewController()
window?.rootViewController = UINavigationController(rootViewController: viewController)
return true
}
}
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleUserLoggedOut))
}
#objc func handleUserLoggedOut() {
UserDefaults.standard.set(false, forKey: "isUserLoggedIn")
UIApplication.shared.keyWindow?.rootViewController = UINavigationController(rootViewController: LoginViewController())
}
}
class LoginViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Login", style: .plain, target: self, action: #selector(handleUserLoggedIn))
}
#objc func handleUserLoggedIn() {
UserDefaults.standard.set(true, forKey: "isUserLoggedIn")
UIApplication.shared.keyWindow?.rootViewController = UINavigationController(rootViewController: MainViewController())
}
}
This is only a skeleton. Give both controller different background colours and button action to call handleUserLoginIn and handleUserLoggedOut on respective controllers and see how it works. Play around with it and figure out.
Note: keyWindow is deprecated so you need to use this instead at all places.
let keyWindow = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.map({$0 as? UIWindowScene})
.compactMap({$0})
.first?.windows
.filter({$0.isKeyWindow}).first
Edit: I've also added the login, logout buttons and set backgroundColors for you to see for yourself the result.

How to skip 2 ViewController correctly

Tell me, please, what am I doing wrong?
There are 3 View:
The user selects his gender
The user enters his weight
Main View Application
After the user has written this data, he gets to the main screen of the application. I want to make the user choose his gender and weight only at the very first launch of the application. To do this, I created a UserSettings model to store the entered values there:
final class UserSettings {
enum SettingsKeys: String {
case userSex
case userWeight
}
static var userSex: String! {
get {
return UserDefaults.standard.string(forKey: SettingsKeys.userSex.rawValue)
}
set {
let defaults = UserDefaults.standard
let key = SettingsKeys.userSex.rawValue
if let sex = newValue {
print("Пол \(sex) добавлен в \(key)")
defaults.set(sex, forKey: key)
} else {
defaults.removeObject(forKey: key)
}
}
}
static var userWeight: String! {
get {
return UserDefaults.standard.string(forKey: SettingsKeys.userWeight.rawValue)
}
set {
let defaults = UserDefaults.standard
let key = SettingsKeys.userWeight.rawValue
if let weight = newValue {
print("Вес \(weight) добавлен в \(key)")
defaults.set(weight, forKey: key)
} else {
defaults.removeObject(forKey: key)
}
}
}
}
In AppDelegate in function didFinishLaunchingWithOptions launchOptions wrote:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let defaults = UserDefaults.standard
let skipPageSex = defaults.bool(forKey: UserSettings.userSex)
let skipPageWeight = defaults.bool(forKey: UserSettings.userWeight)
if skipPageSex && skipPageWeight == true {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let nextView: MainViewController = mainStoryboard.instantiateViewController(identifier: "MainViewController") as! MainViewController
window?.rootViewController = nextView
self.window?.makeKeyAndVisible()
} else {
let firstStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let firstView: WelcomeViewController = firstStoryboard.instantiateViewController(identifier: "welcomeVC") as! WelcomeViewController
window?.rootViewController = firstView
self.window?.makeKeyAndVisible()
}
return true
}
In the Sex select View in the button action, I wrote:
#IBAction func manSelected(_ sender: UIButton) {
sender.setTitle("Male", for: .normal)
UserSettings.userSex = sender.currentTitle
let defaults = UserDefaults.standard
defaults.setValue(true, forKey: UserSettings.userSex)
defaults.synchronize()
}
And the same for the button with the female choice, only sender.setTitle("Female", for: .normal)
I tried removing UIMainStoryboardFile and UIApplicationSceneManifest in Info.plist and in this case I get just a black screen without errors. In the Storyboard ID I use the same value as in AppDelegate. Please, help
Try something like this. Initial with a TempViewController. Depend on your data, it will segue perform show Gender Picker or go directly to Main. Remember to check the Is Initial View Controller for root Navigation Controller.

NSUserDefault Value found nil with kill the App

I just trying to save the user Id and status as true value in UserDefaults when they login or Register with App.
UserDefaults.standard.set(user?.CustID, forKey: "CustID")
UserDefaults.standard.set(true, forKey: "status")
so when the user reopen the app in my Appdelegate I check the Status if it's true then user directly pass on HomeScreen and if the status False its pass on login screen.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let status = UserDefaults.standard.bool(forKey: "status")
if (status == true) && (custID != "") {
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "HomeTicketViewController") as! HomeTicketViewController
let navigationController = UINavigationController(rootViewController: nextViewController)
let appdelegate = UIApplication.shared.delegate as! AppDelegate
appdelegate.window!.rootViewController = navigationController
}else {
let storyBoard : UIStoryboard = UIStoryboard(name: "Login", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
let navigationController = UINavigationController(rootViewController: nextViewController)
let appdelegate = UIApplication.shared.delegate as! AppDelegate
appdelegate.window!.rootViewController = navigationController
}
}
I get the status true but i found that The CustID found nil.
Is there any solution for that?
In userdefault if value not found in userdefaults corresponding to key then userdefault return nil and in case of bool it returns false.
In your case, when you app launches, app does not have any value corresponding to custID so you getting nil.
You need to add check like this
if (status == true) && (custID != nil){
:
:
}
The default is false
let status = UserDefaults.standard.bool(forKey: "status")
so status will be false at first , also status being true doesn't mean CustID saved no nil
UserDefaults.standard.set(user!.CustID, forKey: "CustID")
as user may be nil so force-unwrap to verify that

Unable to navigate to specific viewController after clicking push notification in foreground using FCM below iOS 10

I am trying to get the notification in foreground as well as in background, i am getting notification in both states, but i'm unable to navigate it to desired view controller after tapping the notification when app is in foreground, Any help will be highly appreciated, thanks in advance
i am using third party for custom banner, running on iphone 4s device, ios 9
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)
print("In did Recieve Notification")
// Print message ID.
print("userInfoNotification=\(userInfo)")
if let contactID = userInfo["contactID"] as? String {
self.contactID = contactID
print(contactID)
}
let state = UIApplication.shared.applicationState
if state == .active {
print("App in Foreground")
if self.contactID != AppDelegate.openedChatContactId {
print("openedID=\(AppDelegate.openedChatContactId)")
if let aps = userInfo["aps"] as? NSDictionary {
if let alert = aps["alert"] as? NSDictionary {
let body = alert["body"] as! String
let title = alert["title"] as! String
let banner = Banner(title: title, subtitle: body, image: UIImage(named: "AppIcon"), backgroundColor: UIColor(red:31.00/255.0, green:136.0/255.0, blue:254.5/255.0, alpha:1.000))
banner.dismissesOnTap = true
banner.show(duration: 3.0)
// let storyboard = UIStoryboard(name: "Main", bundle: nil)
// let viewController = storyboard.instantiateViewController(withIdentifier: "chatMessageVC") as! ChatMessagesVC
// UIApplication.shared.keyWindow?.rootViewController = viewController;
} else if let alert = aps["alert"] as? NSString {
}
}
}
}
if state == .inactive || state == .background {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var destinationViewController = storyboard.instantiateViewController(withIdentifier: "chatMessageVC") as! ChatMessagesVC
UserDefaults.standard.set(contactID, forKey: "contactID")
UserDefaults.standard.synchronize()
destinationViewController.contactID = self.contactID
let navigationController = self.window?.rootViewController as! UINavigationController
navigationController.pushViewController(destinationViewController, animated: false)
}
}
Implement below extension of UIApplication
extension UIApplication {
class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let navigationController = controller as? UINavigationController {
return topViewController(controller: navigationController.visibleViewController)
}
if let tabController = controller as? UITabBarController {
if let selected = tabController.selectedViewController {
return topViewController(controller: selected)
}
}
if let presented = controller?.presentedViewController {
return topViewController(controller: presented)
}
return controller
}
}
Please change your code to navigate to specific screen while app is in foreground.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "chatMessageVC") as! ChatMessagesVC
UIApplication.topViewController()?.navigationController?.pushViewController(viewController, animated: false)
Hope this finds you well and let me know in case of any queries.
UPDATE
If the application is running in the foreground, iOS won't show a notification banner/alert. That's by design. But we can achieve it by using UILocalNotification as follows
if application.applicationState == .active {
var localNotification = UILocalNotification()
localNotification.userInfo = userInfo
localNotification.soundName = UILocalNotificationDefaultSoundName
localNotification.alertBody = message
localNotification.fireDate = Date()
UIApplication.shared.scheduleLocalNotification(localNotification)
}

Logout From application in application Settings

I want to logout from application using settings bundle.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//enable_logout key for logout switch identifire in setting budle plist.
let userLogout = UserDefaults.standard.bool(forKey: "enabled_logout")
print(userLogout)
let userLogin = UserDefaults.standard.bool(forKey: "isUserLogin")
if userLogin {
let homeController = HomeController()
let homeNav = UINavigationController.init(rootViewController: homeController)
let aboutController = AboutController()
let aboutNav = UINavigationController.init(rootViewController: aboutController)
let userBaseController = UserBaseInfoController()
let userBaseNav = UINavigationController.init(rootViewController: userBaseController)
tabbarController.viewControllers =[homeNav,userBaseNav,aboutNav]
self.window?.rootViewController = tabbarController
}
else {
let login = LoginController()
self.window?.rootViewController = login
}
return true
}
I'm added this code in appDelegate, I want to when the user enables logout switch in setting and then return to application show login view, but when enables switch and back to app appDelegate not call and my key not change.
There is my setting view :
I am solve this problem, instead check enable_logout key in didFinishLaunchingWithOptions method, I checked in applicationWillEnterForeground methods.
Here is my code:
func applicationWillEnterForeground(_ application: UIApplication) {
let userLogout = UserDefaults.standard.bool(forKey: "enable_logout")
print(userLogout)
if !userLogout {
let homeController = HomeController()
let homeNav = UINavigationController.init(rootViewController: homeController)
let aboutController = AboutController()
let aboutNav = UINavigationController.init(rootViewController: aboutController)
let userBaseController = UserBaseInfoController()
let userBaseNav = UINavigationController.init(rootViewController: userBaseController)
tabbarController.viewControllers = [homeNav,userBaseNav,aboutNav]
self.window?.rootViewController = tabbarController
}
else {
let login = LoginController()
self.window?.rootViewController = login
}
}

Resources