Delegate Method is not called in Swift? - swift

I want to pass a Bool value from on view controller to another without the help of segues. So i referred & got Delegates.
I have applied delegates in my App. But the Delegate method is not being called. I don't know where i am making the mistake.
So Please help me.
MainViewController
class MainViewController: UIViewController, WriteValueBackDelegate {
#IBOutlet weak var LoginButton: UIButton!
var LoggedInL :Bool?
override func viewDidLoad() {
super.viewDidLoad()
}
func writeValueBack(value: Bool) {
println("Delegate Method")
if (value == true){
LoginButton.setTitle("My Profile", forState:UIControlState.Normal)
}
}
Second View Controller
class LoginController: UIViewController {
#IBOutlet weak var LoginLabel: UILabel!
#IBOutlet weak var email: UITextField!
#IBOutlet weak var pwd: UITextField!
var LoggedInL :Bool?
var mydelegate: WriteValueBackDelegate?
override func viewDidLoad() {
super.viewDidLoad() }
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func onSubmit(sender: AnyObject) {
Alamofire.request(.GET, "http://www.jive.com/index.php/capp/user_verification/\(email.text)/\(pwd.text)")
.responseJSON { (_, _, data, _) in
println(data)
let json = JSON(data!)
let name = json["first_name"].stringValue
let status = json["valid_status"].intValue
println(status)
var e = self.email.text
println(e)
self.LoginLabel.text = "Hey \(name)!"
if status == 1{
println("Correect")
self.LoggedInL = true
self.mydelegate?.writeValueBack(true)
}else {
self.LoggedInL = false
println("Error")
}
}
navigationController!.popViewControllerAnimated(true)
}
}
protocol WriteValueBackDelegate {
func writeValueBack(value: Bool)
}

you didn't initialize the delegate, and no need to, delegates are usually for async callbacks. do that instead:
class MainViewController: UIViewController {
static var sharedInstace : MainViewController?;
#IBOutlet weak var LoginButton: UIButton!
var LoggedInL :Bool?
override func viewDidLoad() {
super.viewDidLoad()
MainViewController.sharedInstace = self; //this is better from init function
}
func writeValueBack(value: Bool) {
println("Delegate Method")
if (value == true){
LoginButton.setTitle("My Profile", forState:UIControlState.Normal)
}
}
}
in login view controller
MainViewController.sharedInstance?.writeValueBack(true)

In MainViewControlleryou need a reference of the LoginController instance maybe with an IBOutlet and then set the delegate in viewDidLoad
#IBOutlet weak var loginController : LoginController!
override func viewDidLoad() {
super.viewDidLoad()
loginController.mydelegate = self
}

Related

Force unwrapping nil optional for UIImageView when transitioning to view controller

I'm running into an error when transitioning to view controllers by overriding the built-in prepare() function in Swift. I have a UIImageView for backgrounds on my screens. Here is the code for two of the view controllers in question.
import UIKit
import FirebaseAuth
class HomeVC: UIViewController {
#IBOutlet weak var signOutButton: UIButton!
#IBOutlet weak var backgroundImageView: UIImageView!
#IBOutlet weak var friendsNavButton: UIButton!
#IBOutlet weak var homeNavButton: UIButton!
#IBOutlet weak var profileNavButton: UIButton!
#IBOutlet weak var bumpButton: UIButton!
#IBOutlet weak var welcomeLabel: UILabel!
#IBOutlet weak var doNotDisturbLabel: UILabel!
#IBOutlet weak var doNotDisturbButton: UIButton!
var userName = ""
var dndIsOn: Bool = false
#IBAction func dndToggled(_ sender: Any) {
dndIsOn = !dndIsOn
User.current.available = !dndIsOn
FirestoreService.db.collection(Constants.Firestore.Collections.users).document(User.current.uid).updateData([Constants.Firestore.Keys.available : !dndIsOn])
if dndIsOn {
print("DND is on!")
setupDNDUI()
} else if !dndIsOn {
print("DND is off!")
setupActiveUI()
}
}
#IBAction func signOutTapped(_ sender: Any) {
let firAuth = Auth.auth()
do {
try firAuth.signOut()
} catch let signOutError as NSError {
print ("Error signing out: %#", signOutError)
}
print("Successfully signed out")
}
#IBAction func bumpTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toCall, sender: self)
}
#IBAction func friendsNavTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toFriends, sender: self)
}
#IBAction func profileNavTapped(_ sender: Any) {
let nav = self.navigationController //grab an instance of the current navigationController
DispatchQueue.main.async { //make sure all UI updates are on the main thread.
nav?.view.layer.add(CATransition().segueFromLeft(), forKey: nil)
nav?.pushViewController(ProfileVC(), animated: false)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(true, animated: true)
self.backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill
doNotDisturbLabel.isHidden = true
if !userName.isEmpty {
welcomeLabel.text = "Welcome Back, " + userName + "!"
} else {
welcomeLabel.text = ""
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .darkContent
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let friendsVC = segue.destination as? FriendsVC else {
return
}
FirestoreService.db.collection(Constants.Firestore.Collections.users).document(User.current.uid).getDocument { (snapshot, err) in
if let err = err {
print(err.localizedDescription)
} else {
let data = snapshot!.data()!
let requests = data[Constants.Firestore.Keys.requests] as? [String]
if let requests = requests {
friendsVC.requests = requests
}
}
}
}
class FriendsVC: UIViewController {
//var friends: [Friend] = User.current.friends
var friends: [User] = []
var requests: [String]?
#IBOutlet weak var requestsNumberLabel: UILabel!
#IBOutlet weak var backgroundImageView: UIImageView!
#IBOutlet weak var friendRequestsButton: UIButton!
#IBOutlet weak var homeNavButton: UIButton!
#IBOutlet weak var friendsTitle: UILabel!
#IBOutlet weak var friendTableView: UITableView!
#IBOutlet weak var addFriendButton: UIButton!
#IBOutlet weak var tableViewTopConstraint: NSLayoutConstraint!
#IBAction func friendRequestsTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toRequests, sender: self)
}
#IBAction func homeNavTapped(_ sender: Any) {
let nav = self.navigationController //grab an instance of the current navigationController
DispatchQueue.main.async { //make sure all UI updates are on the main thread.
nav?.view.layer.add(CATransition().segueFromLeft(), forKey: nil)
nav?.pushViewController(HomeVC(), animated: false)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(true, animated: true)
backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill
friendTableView.backgroundView?.backgroundColor = .white
friendsTitle.isHidden = false
UserService.getUserArray(uids: User.current.friendUids, completion: { (users) in
guard let users = users else {
print("User has no friends")
return
}
self.friends = users
self.friendTableView.reloadData()
})
guard let requests = self.requests else {
friendRequestsButton.isHidden = true
requestsNumberLabel.isHidden = true
self.tableViewTopConstraint.constant = 0
return
}
requestsNumberLabel.text = requests.count.description
// Do any additional setup after loading the view.
friendTableView.delegate = self
friendTableView.dataSource = self
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let homeVC = segue.destination as? HomeVC {
homeVC.userName = User.current.firstName
} else if let requestsVC = segue.destination as? RequestsVC {
UserService.getUserArray(uids: self.requests!) { (requesters) in
if let requesters = requesters {
requestsVC.requesters = requesters
}
}
}
}
}
When my app loads into the home screen, there is no problem, and when a button is tapped to transition to FriendsVC, there is no problem. However, when I try to initiate the transition from HomeVC to ProfileVC or from FriendVC to HomeVC, I get the error: "Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value" at the self.backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill lines in my viewDidLoad methods. These segues have something in common in that these are the ones where I override the prepare() function, but I'm not sure what I'm doing wrong

How to use functions from other swift files (same target) in same project

Hey I have 2 Classes each in own swift file. Im basically doing this only to get a better overview in my Viewcontroller. Still, I need to get access to the data or call the func from other files in my view controller.swift file. Its in the same Target so I don't need to import it in my view controller file right?
If I do override the func viewDidLoad() I get an Exception so I guess I am only allowed to do it once (-> in my viewController.swift)
//ViewController.swift
class ViewController: UIViewController{
#IBOutlet weak var xMotion: UILabel!
#IBOutlet weak var yMotion: UILabel!
#IBOutlet weak var zMotion: UILabel!
#IBOutlet weak var lineChartView: LineChartView!
#IBOutlet weak var lineChartView2: LineChartView!
override func viewDidLoad() {
super.viewDidLoad()
timebuffer.append(Double(ts1))
colors.append(UIColor.red)
Graphen.customizeChart(values: buffer1.map { Double($0) })
Graphen.filteredChart(values: buffer2.map { Double($0) })
Graphen.multipleCharts()
}
//Graphen.swift
class Graphen : ViewController
{
//creates Plot with specific numbers/data
func customizeChart(values: [Double]){
var dataEntries: [ChartDataEntry] = []
for i in 0..<buffer1.count{//dataPoints.count
let dataEntry = ChartDataEntry(x: Double(i), y: values[i])
dataEntries.append(dataEntry) }
lineChartDataSet = LineChartDataSet(entries: dataEntries, label: nil)
lineChartDataSet.circleRadius = 0.5
let lineChartData = LineChartData(dataSet: lineChartDataSet)
self.lineChartView.data = lineChartData
}
}
viewDidLoad() is a lifecycle method of a UIViewController's instance. Thus, it can be overridden in each UIViewCiontroller subclass, i.e.
class ViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
//your code here...
}
}
class Graphen : ViewController
{
override func viewDidLoad() {
super.viewDidLoad()
//your code here...
}
}
Now, you don't need to import any file/class as long as they are in the same target.
Now, since Graphen's customizeChart(values:) method is an instance method, so you need to create an instance of Graphen first and then use it to call its instance methods like so,
let graphen = Graphen()
graphen.customizeChart(values: buffer1.map { Double($0) })
Similarly call other instance methods of Graphen. Assuming that filteredChart(values:) and multipleCharts() are also instance methods, you can invoke them like,
graphen.filteredChart(values: buffer2.map { Double($0) })
graphen.multipleCharts()

I have a problem with a variable in AppDelegate

I have an error in my code when trying to return a variable that is in the App delegate to a viewController, it returns a null value and therefore does not assign the delegate
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var client: SINClient!
.
.
.
}
class ViewController: UIViewController, SINCallClientDelegate {
#IBOutlet weak var destination: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func client() -> SINClient? {
return (UIApplication.shared.delegate as! AppDelegate).client
}
override func awakeFromNib() {
super.awakeFromNib()
self.client()?.call().delegate = self
}
#IBAction func actionCall(_ sender: UIButton) {
if destination.text != "" && self.client()!.isStarted() {
weak var call = client()!.call().callUserVideo(withId: destination.text)
performSegue(withIdentifier: "callView", sender: call)
}
}
func client(_ client: SINCallClient?, didReceiveIncomingCall call: SINCall?) {
performSegue(withIdentifier: "callView", sender: call)
}
}
Fatal error: Unexpectedly found nil while unwrapping an Optional value

Having issues passing a delegate from NSWindowController subclass to my ViewController

I'm having issues with passing a custom protocol (MainWindowControllerProtocol) to the EditorViewController from the MainWindowController, which is subclass of NSWindowController. Please help.
EditorViewController.swift
extension EditorViewController: MainWindowControllerProtocol {
func didOpenFile() {
print("TODO: Open File") // never called, but it should be
}
}
class EditorViewController: NSViewController {
// - IBOutlets
#IBOutlet weak var treeOutlineView: NSOutlineView!
#IBOutlet var codeTextView: NSTextView!
#IBOutlet weak var counterTextField: NSTextField!
#IBOutlet weak var languageTextField: NSTextField!
//public var editor = Editor()
//var rootNode: Node?
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
//rootNode = Path(Path.userDownloads).node
// Issue is here
if let windowController = NSApplication.shared.mainWindow?.windowController as? MainWindowController {
windowController.delegate = self
}
else {
print("Doesnt work") // prints this
}
//treeOutlineView.reloadData()
}
}
MainWindowController
public protocol MainWindowControllerProtocol {
func didOpenFile()
}
class MainWindowController: NSWindowController {
var delegate: MainWindowControllerProtocol?
override func windowDidLoad() {
super.windowDidLoad()
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
#IBAction func openFile(_ sender: Any) {
print("In here") // this is called?
delegate?.didOpenFile() // but this never is apparently
}
}
Maybe this topic should help.
This method might return nil if the application’s nib file hasn’t
finished loading, if the receiver is not active, or if the application
is hidden.
Have you checked if NSApplication.shared.mainWindow is nil or just NSApplication.shared.mainWindow?.windowController cannot be casted to your controller class ?

Navigation Controller Error

I have a navigation controller and I want the title to have a custom font. I have tried to do this but when it runs I get Thread 1: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP.subcode=0x0)
Here is my code.
import UIKit
class PriceCheckSpreadsheetViewController: UIViewController {
#IBOutlet weak var SpreadsheetView: UIWebView!
#IBOutlet weak var Loading: UIActivityIndicatorView!
#IBOutlet weak var BackButton: UIBarButtonItem!
#IBOutlet weak var ForwardButton: UIBarButtonItem!
#IBOutlet weak var NaviBar: UINavigationItem!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let url = "http://www.backpack.tf/pricelist/spreadsheet"
let requestURL = NSURL(string: url)
let request = NSURLRequest(URL: requestURL!)
SpreadsheetView.loadRequest(request)
self.navigationController?.navigationBar.titleTextAttributes = [ NSFontAttributeName: UIFont(name: "TF2Build", size: 12)!]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func webViewDidStartLoad(_ : UIWebView) {
Loading.startAnimating()
NSLog("Loading")
}
func webViewDidFinishLoad(_ : UIWebView) {
Loading.stopAnimating()
NSLog("Done")
if SpreadsheetView.canGoBack {
BackButton.enabled = true
}
else {
BackButton.enabled = false
}
if SpreadsheetView.canGoForward {
ForwardButton.enabled = true
}
else {
ForwardButton.enabled = false
}
}
#IBAction func Reload(sender: AnyObject) {
SpreadsheetView.reload()
}
#IBAction func Back(sender: AnyObject) {
SpreadsheetView.goBack()
}
#IBAction func Forward(sender: AnyObject) {
SpreadsheetView.goForward()
}
}