Kevin Kevin - 5 months ago 41
Swift Question

Move to new view after contact is select from CNContactPickerViewController

I'm writing a concept chat app. I'm now at the point where a new chat could be started.

What I want is that when the user selects a contact using the

CNContactPickerViewController
, the picker is dismissed (this is working) and the contact details are send to a new chat view (this is not working). The error I get is that at
func contactPicker
the
delegate
returns
nil
. I have been following this tutorial in getting contact data from the ChatsViewController to the ChatViewController. The relevant code:

import UIKit
import Contacts
import ContactsUI

class ChatsViewController: UITableViewController, CNContactPickerDelegate {
var chats:[Chat] = chatData
var selectedContact: CNContact = CNContact()
@IBAction func createNewChat(sender: AnyObject) {
let contactPickerViewController = CNContactPickerViewController()
contactPickerViewController.delegate = self
presentViewController(contactPickerViewController, animated: true, completion: nil)
}

override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return chats.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ChatCell", forIndexPath: indexPath) as! ChatCell

let chat = chats[indexPath.row] as Chat
cell.chat = chat
return cell
}

func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
self.selectedContact = contact
self.performSegueWithIdentifier("idContactSelected", sender: self)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "idContactSelected" {
let chatVC = segue.destinationViewController as! ChatViewController
chatVC.contact = self.selectedContact
}
}
}


And this is the new chat ViewController.

import UIKit
import Contacts
import ContactsUI

class ChatViewController: UIViewController {

@IBOutlet weak var testLabel: UILabel!
var contact: CNContact = CNContact()

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.testLabel.text = contact.givenName
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}


So in recap: I have a ViewController, I can press a button there to start a new chat, which opens the contact picker. Once a contact is selected, the
func contactPicker
is executed, but the contact data is never sent, nor the new chat ViewController is presented and the
delegate
is
nil
. Why is this happening? I assume it is because
delegate
is never set, only created, but in the tutorial this is all they do and it seems to work.

Thanks in advance for any thoughts on this.

EDIT: Solution in the end: I didn't need the delegate, I can just push data through
prepareForSegueWithIdentifier
. Also, the segue was not connected properly, reconnecting the segue fixed the transition not working.

Answer

Try some thing like this. Change your code something like this

ChatsViewController

import UIKit
import Contacts
import ContactsUI

class ChatsViewController: UITableViewController, CNContactPickerDelegate {
    var chats:[Chat] = chatData
    var selectedContact: CNContact = CNContact()
    @IBAction func createNewChat(sender: AnyObject) {
        let contactPickerViewController = CNContactPickerViewController()
        contactPickerViewController.delegate = self
        presentViewController(contactPickerViewController, animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false
        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return chats.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("ChatCell", forIndexPath: indexPath) as! ChatCell

        let chat = chats[indexPath.row] as Chat
        cell.chat = chat
        return cell
    }

    func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
         self.selectedContact = contact
         self.performSegueWithIdentifier("idContactSelected", sender: self)
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
         if segue.identifier == "idContactSelected" {
             let chatVC = segue.destinationViewController as! ChatViewController
             chatVC.contact = self.selectedContact
         }
    }
}

After that change your ChatViewController

import UIKit
import Contacts
import ContactsUI
class ChatViewController: UIViewController {

     @IBOutlet weak var testLabel: UILabel!
     var contact: CNContact = CNContact()

     override func viewDidLoad() {
         super.viewDidLoad()
         // Do any additional setup after loading the view.
         self.testLabel.text = contact.givenName
     }

     override func didReceiveMemoryWarning() {
         super.didReceiveMemoryWarning()
         // Dispose of any resources that can be recreated.
     }
}

Hope this will help you.

Comments