load viewController from class in swift - swift

Hi i am start to develop in swift recently and i am little confuse.
I have login system that know if the user authenticate or not.
The model check if the user authenticate or not login - by loginManager type NSObject.
after the loginManager verfiy if the user login it need to load the correct storyBoard.
I have viewController -> ProfileViewController, how I can load programaticly this ViewController from loginManager in real Time?
Hi try to call this funcation but I get black Screen, I dont know what do to
override init() {
var profileViewController = profileViewController()
let storyboard:UIStoryboard = UIStoryboard(name:"Main", bundle:nil)
let vc:UIViewController = storyboard.instantiateViewControllerWithIdentifier("profileViewController") as profileViewController
vc.navigationController?.pushViewController(profileViewController, animated: true)
vc.viewWillAppear(true)
}

Related

swift pushkit -> open call screen without open total app

I have some problem with my app, the exactly I want is to only open call screen when get pushkit VOIP call. But the problem is that the app gets open again(when killed), so many request were sent to server, i just want to open only callscreen, then may exit app after call dismiss.
I will fully explain the problem now:
First, in app delegate i replace with this class(this class have same UI with splash Screen)
initiateFirstScreen("SplashScreen", storyboardName : "sheet")
Inside this class. I have to check token, user info, connect to signalr server, it's took about 5-8 seconds, and when all loaded, i call this function to navigate to the HomeScreen:
func checkLogin() {
if let oauth = AppDelegate.shared.authState, oauth.isAuthorized{
initiateFirstScreen("HomeVC", storyboardName : "main")
}else{
initiateFirstScreen("LoginVC", storyboardName : "main")
}
}
func initiateFirstScreen(_ vcName: String, storyboardName : String) {
guard let window = AppDelegate.shared.window else{
AlertUtils.alertMessageWithOkAction(vc: self, mes: Language.get("Something went wrong")){b in
exit(0)
}
return
}
let storyBoard: UIStoryboard = UIStoryboard(name: storyboardName, bundle: nil)
let vc = storyBoard.instantiateViewController(withIdentifier: vcName)
window.rootViewController = vc
window.makeKeyAndVisible()
}
Inside above code, im using window.rootViewController = vc to dislay HomeScreen without any animation.
The problem:
Because of long loading in SplashScreen, when I got pushKit -> show Callkit screen, user may took 3-4 seconds to answer(when the app is killed/swiped)
-> didFinishLaunchingWithOptions called
-> SplashScreen called, and while user is answering call, the "check token, user info, connect to signalr" is loaded
-> Hence, the below function called:
window.rootViewController = vc
window.makeKeyAndVisible()
-> It's clear my callscreen now, that is the problem.
So i want to solved this problem, sorry for my silly question, but it's make me waste 3 days but can not solved this :(
You can use the delegate
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession)
This delegate gets call when you answer the call. So just navigate directly to call screen. and add a flag eg. isCall = true and prevent the user to navigate to Home Screen this time

Swift: [NSNib _initWithNibNamed:bundle:options:] could not load the nibName

I am building a Cocoa app for production and when I create an NSViewController for routing without NSStoryboard instantiate, I got the error like below.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[NSNib _initWithNibNamed:bundle:options:] could not load the nibName: ContentFully.AnotherController in bundle (null).
Actually I solved my problem via using an NSViewController to adding NSStoryboard but I would like to learn what is going on when I call it programmatically and why did crash?
Working scenario
let storyboard = NSStoryboard(name: "Dashboard", bundle: nil)
let vc = storyboard.instantiateInitialController() as! AnotherController
Crashed scenario
let vc = AnotherController()
self.view.window?.contentViewController = vc
Even if I create a class fully programmatically and non-relational with NSStoryboard I could not use it when I change the contentViewController. Is it necessary to search every controller in NSBundle for Swift?
Thanks in advance
A very simple working version would be:
import Cocoa
class AnotherController: NSViewController {
override func loadView() {
view = NSView(frame: NSMakeRect(0.0, 0.0, 400.0, 270.0))
let label = NSTextField(labelWithString: "Another Controller")
view.addSubview(label)
}
}
I can call that from my first controller using the code you say crashes and get the expected result.
#IBAction func replaceMe(_ sender: Any) {
let vc = AnotherController()
self.view.window?.contentViewController = vc
}

Transition from a sign in ViewController to a UITabBarController

So I am trying to transition from my sign in viewcontroller to my tabbarcontroller, after a successful login.
When I enter my login details and press the sign in button, I am redirected to the Appdelegate page with a signal SIGABRT error.
I tried using this code in my viewcontroller:
let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "CustomViewController") as! CustomViewController
self.present(mainPage, animated: true, completion: nil)
What's in CustomViewController? If you're instantiating that one directly as a ViewController instead of as a UiTabBarViewController, I'm thinking you will need to add the Sub ViewControllers for each one of the Tabs manually. But it's difficult to be sure without looking at what you have in CustomViewController.
Have you tried to set the application's rootViewController to the UITabBarController instance?
For example, this would set application's rootViewController to the tab bar controller:
let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "CustomViewController") as! CustomViewController
UIApplication.shared.keyWindow?.rootViewController = mainPage

Handle deep link notification

I'm adding deep linking to my app and getting stuck at handing off the URL to the view controller. I try to use notification but it doesn't work all the times.
My App Delegate:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let notification = Notification(name: "DeepLink", object: url)
NotificationCenter.default.post(notification)
return true
}
}
And View Controller:
class ViewController: UIViewController {
func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.handleDeepLink), name: "DeepLink", object: nil)
}
#objc private func handleDeepLink(notification: Notification) {
let url = notification.object as! URL
print(url)
}
}
Problem: when my app is cold launched the notification is not handled, which I guess is due to the View Controller not having time to register itself as the observer yet. If I press the Home button, go to Notes and click on the deep link a second time, everything works as it should.
Question: how can I register the View Controller to observe the notification when the app is cold launched? Or is there a better way to send the URL from the App Delegate to the View Controller?
I think an initial assumption is to assume your view controller does not have time to register itself which means that the connection between URL and View controller must be decoupled and reside outside of the view controller.
I would then use some kind of lookup to instantiate the view controller when a URL is received.
For example,
if url.contains(“x”) {
let vc = ViewController(...)
cv.url = URL // Pass contextual data to the view controller.
// Present or push cv
}
As your app gets more complex you have to manage more challenging scenarios, like standing-up entire controller stacks, or removing presented controllers.
I followed the example in the LaunchMe app. Here's what solved my problem:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
// My root view controller is a UINavigationController
// Cast this to whatever class your root view controller is
guard let navigationController = self.window?.rootViewController as? UINavigationController else {
return false
}
// Navigate to the view controller that handles the URL within the navigation stack
navigationController.popToRootViewController(animated: false)
// Handle the URL
let vc = navigationController.topViewController as! ViewController
vc.handleDeepLink(url: url)
return true
}
Store if notification is not handled and load it when viewDidLoad.
var pendingNotificationInfo: PushNotificationInfo?

Swift: How to access in AppDelegate variable from the View controller?

I would like to write in the text or csv (prefer) file the variable from the view controller.
Indeed I am doing a drawing app and I would like to write in the file the current position of the finger.
class ViewController: UIViewController {var lastPoint = CGPoint.zeroPoint ... }
I would like to have access to lastPoint.x and lastPoint.y from the AppDelegate. how I could do that ? Thank you.
Your question is full of confusion but if that's what you are looking for:
You can access the appDelegate by getting a reference to it like that:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
after that if you have store a property called lastPoint in your appDelegate you can access its components very simply like that:
let x = appDelegate.lastPoint.x
let y = appDelegate.lastPoint.y
If you need to access your viewController properties from the AppDelegate, then I suggest having a reference to your view controller in your appdelegate:
var myViewController: ViewController!
then when your view controller is created you can store a reference to it in the appdelegate property:
If your create your view controller outside of your appDelegate:
Swift 1-2 syntax
var theViewController = ViewController()
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.myViewController = theViewController
Swift 3-4 syntax
var theViewController = ViewController()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myViewController = theViewController
If you create your view controller inside of your appDelegate:
self.myViewController = ViewController()
After that you can access your data from your viewcontroller from your appdelegate just by accessing its property like that:
let x = self.myViewController.lastPoint.x
let y = self.myViewController.lastPoint.y
Swift 3 Update
var theViewController = ViewController()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myViewController = theViewController
You can create a BaseViewController and write this
class BaseViewController {
lazy var appDelegate : AppDelegate {
return UIApplication.shared.delegate as? AppDelegate
}
}
and inherit other viewcontrollers with BaseViewController and access this by
class ViewController : BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(self.appDelegate?.lastPoint.x)
print(self.appDelegate?.lastPoint.x)
}}
I did manage to access my ViewController from the App delegate by creating an instance of ViewController in AppDelegate.swift, like:
var mainViewController = ViewController()
func applicationWillEnterForeground(_ application: UIApplication) {
mainViewController.myVariable = "Hello".
}
Still, I don't understand how does the AppDelegate "know" that mainViewController is supposed to point to that particular ViewController. As my application has a single view and a single ViewController, that's fine, but what it I had multiple ViewControllers associated with different UIViews? Appreciate if anyone here can shed a light into that.
Best Regards,
Andre