How to use presentViewController in a custom class?

763 Views Asked by At

I just update my code, but the alertWindow won't show up. I add break point in Xcode, it shows that the viewDelegate is nil. All delegates are nil. This is my code:

class LoginViewController:UIViewController,AlertDelegate
{
override func viewDidLoad() {
    super.viewDidLoad()

    let BackGroundImage:UIImageView = UIImageView(frame: CGRectMake(0, 0, self.view.frame.width , self.view.frame.height))

    let image: UIImage = UIImage(named: "backgroundLogin.jpg")!

    BackGroundImage.image = image
    self.view.addSubview(BackGroundImage)
    //self.view.backgroundColor = UIColor(patternImage: UIImage(named: "backgroundLogin.jpg")!)

    username.text = "User name"
    password.text = "Password"
    usernameWarning.text = ""
    passwordWarning.text = ""

    self.view.bringSubviewToFront(username)
    self.view.bringSubviewToFront(password)
    self.view.bringSubviewToFront(usernameText)
    self.view.bringSubviewToFront(passwordText)
    self.view.bringSubviewToFront(LoginButton)
    self.view.bringSubviewToFront(RegisterButton)

    self.view.bringSubviewToFront(usernameWarning)
    self.view.bringSubviewToFront(passwordWarning)


}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    switch segue.identifier
    {


    case .Some("RegisterSegue"):
        let registerViewController = segue.destinationViewController as! RegisterViewController

        if let temp_register_username = usernameText!.text
        {
            registerViewController.register_name = temp_register_username
            if let temp_register_pass = passwordText!.text
            {
                registerViewController.register_password = temp_register_pass
            }
        }
    case .Some("loginSegue"):
        let loginViewController = segue.destinationViewController as! FunctionsViewController
        loginViewController.client = client



    default:
        super.prepareForSegue(segue, sender: sender)



    }
}


override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
    if identifier == "loginSegue"
    {
        if usernameText.text != ""
        {
            if passwordText.text != ""
            {


                let encrypt = encryptMsg(send: passwordText.text!)

                let encrypt_pass = encrypt.encryptSendMsg()

                let sendMsg = AppConfig.AddHead("login", body: usernameText.text!+"|"+encrypt_pass)
                let (_,_) = client.connect(timeout: 1)
                let (success,_) = client.send(str: sendMsg)
                if success
                {
                    let data = client.read(1024*10)
                    if let d = data
                    {
                        if let str = String(bytes: d, encoding: NSUTF8StringEncoding)
                        {
                            if str[0...2] == AppConfig.TransmissionAgreementConfiguration["successLogin"]
                            {
                                AppConfig.StoreUserID(str)

                                let defaults = NSUserDefaults()

                                defaults.setObject(usernameText.text!, forKey: "userName")

                                let acceptThread = AcceptThread()
                                acceptThread.start()

                                return true
                            }
                            else if str[0...2] == AppConfig.TransmissionAgreementConfiguration["errLoginUsernameNotExist"]
                            {
                                usernameWarning.text = "User name doesn't exist"
                                usernameWarning.reloadInputViews()

                                passwordWarning.text = ""
                                passwordWarning.reloadInputViews()
                                return false

                            }
                            else if str[0...2] == AppConfig.TransmissionAgreementConfiguration["errLoginUsernameAlreadyOnline"]
                            {
                                usernameWarning.text = "User account already be online"
                                usernameWarning.reloadInputViews()

                                passwordWarning.text = ""
                                passwordWarning.reloadInputViews()
                                return false
                            }
                            else if str[0...2] == AppConfig.TransmissionAgreementConfiguration["errLoginPassword"]
                            {
                                usernameWarning.text = ""
                                usernameWarning.reloadInputViews()

                                passwordWarning.text = "Password Incorrect"
                                passwordWarning.reloadInputViews()
                                return false
                            }
                        }
                    }
                }

                return false

            }
            else
            {
                usernameWarning.text = ""
                usernameWarning.reloadInputViews()

                passwordWarning.text = "password cannot be empty"
                passwordWarning.reloadInputViews()
                return false
            }

        }
        else
        {
            usernameWarning.text = "username cannot be empty"
            usernameWarning.reloadInputViews()
            return false
        }
    }
    else
    {
        return true
    }

}

func presentWindow(title:String,msg:String)
{

    let alertController = UIAlertController(title: "\(title):", message: "\(msg)", preferredStyle: UIAlertControllerStyle.Alert)
    alertController.addTextFieldWithConfigurationHandler{
        (textField: UITextField!) -> Void in
        textField.placeholder = "Message"
    }

    let cancelAction = UIAlertAction(title: "Ignore", style: UIAlertActionStyle.Cancel, handler: nil)

    let okAction = UIAlertAction(title: "Reply", style: UIAlertActionStyle.Default,
        handler: {
            action in
            let reply_msg = alertController.textFields!.first! as UITextField
            print("I replies \(reply_msg)")

    })
    alertController.addAction(cancelAction)
    alertController.addAction(okAction)
    self.presentViewController(alertController, animated: true, completion: nil)

}
@IBAction func logoutUnwindSegue(segue: UIStoryboardSegue) {
    // Intentionally left blank
}

var client:TCPClient = TCPClient(addr:"localhost",port:8889)


var AppConfig=TransmissionAgreement(first:"test")
@IBOutlet weak var usernameWarning: UILabel!

@IBOutlet weak var passwordWarning: UILabel!

@IBOutlet weak var username: UILabel!
@IBOutlet weak var password: UILabel!

@IBOutlet weak var usernameText: UITextField!
@IBOutlet weak var passwordText: UITextField!

@IBOutlet weak var LoginButton: UIButton!

@IBOutlet weak var RegisterButton: UIButton!
}

class AcceptThread: NSThread {
override func main() {
    let server:TCPServer = TCPServer(addr:"127.0.0.1",port: 7000)

    let (success,_) = server.listen()
    if success
    {

        while !cancelled
        {
            if let my_client = server.accept()
            {

                let clientReadThread = ClientReadThread(client: my_client)
                clientReadThread.start()
                clientThreads.append(clientReadThread)
            }
        }

        for clientThread in clientThreads {
            clientThread.cancel()
        }
    }
}

var clientThreads = Array<ClientReadThread>()
var AppConfig=TransmissionAgreement(first:"test")
}

@objc protocol AlertDelegate: class {
func presentWindow(title:String,msg:String)
}

@objc protocol ClientReadThreadDelegate: class {
func clientReadThread(clientReadThread: ClientReadThread, didReceiveMessage message: String)

}


class ClientReadThread:NSThread{
init(client: TCPClient) {
    self.client = client

     super.init()
}




override func main() {
    while !cancelled, let readValue = client.read(1024*10) {
        if let message = String(bytes: readValue, encoding: NSUTF8StringEncoding) {

            let head = message[0...2]
         //   print("head is \(head)")


            if head! == AppConfig.TransmissionAgreementConfiguration["add"]
            {
                let defaults = NSUserDefaults()
                let myname = defaults.stringForKey("userName")


                    //store data
                    let context = CoreDataService.sharedCoreDataService.mainQueueContext
                    let friend = NSEntityDescription.insertNewObjectForNamedEntity(Friends.self, inManagedObjectContext: context)
                    friend.name = message.substringFromIndex(3)

                    try! context.save()

                    let sendMsg = AppConfig.AddClientHead("agreeAdd", body:myname)

                    let (_,_) = client.send(str:sendMsg)
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        self.delegate?.clientReadThread(self, didReceiveMessage: message)
                    })


            }
            else if head! == AppConfig.TransmissionAgreementConfiguration["chat"]
            {
                let search = message.substringFromIndex(3)
                 let resultController = try? catFriend.sharedCatFriendsService.catBlack(search)
                 try! resultController!.performFetch()

                 let flag = resultController?.sections?.count

                if flag <= 1//friend
                {

                    dispatch_async(dispatch_get_main_queue(), { () -> Void in

                        let client_info = message.split("|")
                        let client_name = client_info[1]

                        //self.alertDelegate?.presentWindow(client_name, msg: client_info[2])
                        self.viewDelegate?.presentWindow(client_name, msg: client_info[2])

                    })


                }
                else//black, not show the meg
                {
                    //do nothing
                }

            }

        }
    }
}

var AppConfig=TransmissionAgreement(first:"test")
let client: TCPClient
var viewDelegate:LoginViewController?
var delegate: ClientReadThreadDelegate?
var alertDelegate: AlertDelegate?
private var resultController: NSFetchedResultsController?
}
1

There are 1 best solutions below

3
On BEST ANSWER

presentViewContoller is a method on UIViewController so you'll need an instance of a view controller to be able to present your alert view.

The way this would normally be done is to have the view controller you have start the ClientReadThread implement the AlertDelegate protocol. There's no reason for ClientReadThread to implement AlertDelegate itself. Would it ever be it's own delegate?

Also you delegate's should be marked weak or else you'll end up with a retain cycle.

class MyViewController : UIViewController, AlertDelegate {
     private var clientReadThread: ClientReadThread?

     override viewDidLoad() {
          super.viewDidLoad();
          clientReadThread = ClientReadThread(someTcpClient)
          clientReadThread.viewDelegate = self
     }

     func presentWindow(title:String,msg:String) {
         // Your code goes here.
     }
}

Your other option would be to pass an instance of a UIViewController into your ClientReadThread and use that to present the alert view. Although that's not the way I would go. the ClientReadThread shouldn't need to know how it's alerts are handled, that should be delegated to another class.