이번부터는 애플 개발자 계정이 필요하므로 나중에 개발자 계정을 만들게 되면 그 때부터 다시 만들어 보겠습니다.



메세지 보낸 시간 만들기


//

//  ChatModel.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import ObjectMapper


class ChatModel: Mappable {

    

    

    

    @objc public var users :Dictionary<String,Bool> = [:] //채팅방에 참여한 사람들

    public var comments :Dictionary<String,Comment> = [:] //채팅방의 대화내용

    required init?(map: Map) {

        

    }

    func mapping(map: Map) {

        users <- map["users"]

        comments <- map["comments"]

    }

    public class Comment :Mappable{

        @objc public var uid : String?

        @objc public var message : String?

        public var timestamp : Int?

        public required init?(map: Map) {

            

        }

        public  func mapping(map: Map) {

            uid <- map["uid"]

            message <- map["message"]

            timestamp <- map["timestamp"]

        }

    }

    

}




//

//  ChatViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import Firebase


class ChatViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    

    

    

    @IBOutlet weak var tableview: UITableView!

    

    

    @IBOutlet weak var textfield_message: UITextField!

    

    @IBOutlet weak var sendButton: UIButton!

    

    var uid : String?

    var chatRoomUid : String?

    

    var comments : [ChatModel.Comment] = []

    var userModel :UserModel?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        uid = Auth.auth().currentUser?.uid

        sendButton.addTarget(self, action: #selector(createRoom), for: .touchUpInside)

        checkChatRoom()

        self.tabBarController?.tabBar.isHidden = true

        // Do any additional setup after loading the view.

    }

    

    //종료

    override func viewWillDisappear(_ animated: Bool) {

        self.tabBarController?.tabBar.isHidden = false

    }

    

    func keyboardWillShow(notification : Notification){


        UIView.animate(withDuration: 0 , animations: {

            self.view.layoutIfNeeded()

        }, completion: {

            (complete) in

            

            if self.comments.count > 0 {

                self.tableview.scrollToRow(at: IndexPath(item: self.comments.count - 1 , section: 0), at: UITableViewScrollPosition.bottom, animated: true)

            }

        })

    }


        /*

        if let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue{

            self.bottomContraint.constant = keyboardSize.height

 

        

    }

        func keyboardWillHide(notification: Notification){

            self.bottomContraint.constant = 20

            self.view.layoutIfNeeded()

        }

 

 

 */

        


    


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return comments.count

    }

    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        

        if(self.comments[indexPath.row].uid == uid){

            let view = tableView.dequeueReusableCell(withIdentifier: "MyMessageCell", for: indexPath) as! MyMessageCell

            view.label_message.text = self.comments[indexPath.row].message

            view.label_message.numberOfLines = 0

            


            if let time = self.comments[indexPath.row].timestamp{

                view.label_timestamp.text = time.toDayTime

            }

            

            

            return view

            

        }else{

            

            let view = tableView.dequeueReusableCell(withIdentifier: "DestinationMessageCell", for: indexPath) as! DestinationMessageCell

            view.label_name.text = userModel?.userName

            view.label_message.text = self.comments[indexPath.row].message

            view.label_message.numberOfLines = 0;

            

            let url = URL(string:(self.userModel?.profileImageUrl)!)

            URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, err) in

                

                DispatchQueue.main.async {

                    

                    view.imageview_profile.image = UIImage(data: data!)

                    view.imageview_profile.layer.cornerRadius = view.imageview_profile.frame.width/2

                    view.imageview_profile.clipsToBounds = true

                    

                }

            }).resume()

            

            if let time = self.comments[indexPath.row].timestamp{

                view.label_timestamp.text = time.toDayTime

            }

            

            

            return view

            

        }

        

        return UITableViewCell()

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return UITableViewAutomaticDimension

    }

    

    

    

    

    public var destinationUid :String? // 나중에 내가 채팅할 대상의 uid

  

    

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

    @objc func createRoom(){

        let createRoomInfo : Dictionary<String,Any> = [ "users" : [

            uid!: true,

            destinationUid! :true

            ]

        ]

        

        

        if(chatRoomUid == nil){

            self.sendButton.isEnabled = false

            // 방 생성 코드

            Database.database().reference().child("chatrooms").childByAutoId().setValue(createRoomInfo, withCompletionBlock: { (err, ref) in

                if(err == nil){

                    self.checkChatRoom()

                }

            })

            

        }else{

            let value :Dictionary<String,Any> = [

                

                "uid" : uid!,

                "message" : textfield_message.text!,

                "timestamp" : ServerValue.timestamp()

            ]

            

            Database.database().reference().child("chatrooms").child(chatRoomUid!).child("comments").childByAutoId().setValue(value, withCompletionBlock: { (err, ref) in

                self.textfield_message.text = ""

            })

        }

        

        

        

        

        

    }

    func checkChatRoom(){

        

        Database.database().reference().child("chatrooms").queryOrdered(byChild: "users/"+uid!).queryEqual(toValue: true).observeSingleEvent(of: DataEventType.value,with: { (datasnapshot) in

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                

                if let chatRoomdic = item.value as? [String:AnyObject]{

                    

                    let chatModel = ChatModel(JSON: chatRoomdic)

                    if(chatModel?.users[self.destinationUid!] == true){

                        self.chatRoomUid = item.key

                        self.sendButton.isEnabled = true

                        self.getDestinationInfo()

                    }

                }

                

                

                

            }

        })

        

    }

    

    func getDestinationInfo(){

        

        Database.database().reference().child("users").child(self.destinationUid!).observeSingleEvent(of: DataEventType.value, with: { (datasnapshot) in

            self.userModel = UserModel()

            self.userModel?.setValuesForKeys(datasnapshot.value as! [String:Any])

            self.getMessageList()

            

        })

    }

    func getMessageList(){

        

        Database.database().reference().child("chatrooms").child(self.chatRoomUid!).child("comments").observe(DataEventType.value, with: { (datasnapshot) in

            self.comments.removeAll()

            

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                let comment = ChatModel.Comment(JSON: item.value as! [String:AnyObject])

                self.comments.append(comment!)

            }

            self.tableview.reloadData()

            

     

            if self.comments.count > 0{

                self.tableview.scrollToRow(at: IndexPath(item:self.comments.count - 1,section:0), at: UITableViewScrollPosition.bottom, animated: true)

                

            }

            

       

        })

        

    }

    

    

    

    /*

     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation

     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

     // Get the new view controller using segue.destinationViewController.

     // Pass the selected object to the new view controller.

     }

     */

    

}



extension Int{

    

    var toDayTime :String{

        let dateFormatter = DateFormatter()

        dateFormatter.locale = Locale(identifier: "ko_KR")

        dateFormatter.dateFormat = "yyyy.MM.dd HH:mm"

        let date = Date(timeIntervalSince1970: Double(self)/1000)

        return dateFormatter.string(from: date)

        

    }

    

}


/*

extension Int{

    var toDayTime :String{

        let dateFormatter = DateFormatter()

        dateFormatter.locale = Locale(identifier: "ko_KR")

        dateFormatter.dateFormat = "yyyy.MM.dd HH:mm"

        let date = Date(timeIntervalSince1970: Double(self)/1000)

        return dateFormatter.string(from: date)

    }

}

*/


class MyMessageCell: UITableViewCell{

    

    @IBOutlet weak var label_message: UILabel!

    @IBOutlet weak var label_timestamp: UILabel!

}


class DestinationMessageCell: UITableViewCell{

    

    @IBOutlet weak var imageview_profile: UIImageView!

    @IBOutlet weak var label_message: UILabel!

    @IBOutlet weak var label_name: UILabel!

    @IBOutlet weak var label_timestamp: UILabel!

}






채팅방에서 상대방 이름과 마지막 메세지 출력되도록 추가



//

//  ChatRoomsViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 16..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//




import UIKit

import Firebase


class ChatRoomsViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    @IBOutlet weak var tableview: UITableView!

    

    var uid : String!

    var chatrooms : [ChatModel]! = []

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        self.uid = Auth.auth().currentUser?.uid

        self.getChatroomsList()

        // Do any additional setup after loading the view.

    }

    

    func getChatroomsList(){

        

        Database.database().reference().child("chatrooms").queryOrdered(byChild: "users/"+uid).queryEqual(toValue: true).observeSingleEvent(of: DataEventType.value, with: {(datasnapshot) in

            

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                self.chatrooms.removeAll()

                if let chatroomdic = item.value as? [String:AnyObject]{

                    let chatModel = ChatModel(JSON: chatroomdic)

                    self.chatrooms.append(chatModel!)

                }

                

            }

            self.tableview.reloadData()

            

            

        })

        

        

        

    }

    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return self.chatrooms.count

    }

    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "RowCell", for:indexPath) as! CustomCell

        

        var destinationUid: String?

        

        for item in chatrooms[indexPath.row].users{

            if(item.key != self.uid){

                destinationUid = item.key

            }

        }

        Database.database().reference().child("users").child(destinationUid!).observeSingleEvent(of: DataEventType.value, with: { (datasnapshot) in

            

            let userModel = UserModel()

            userModel.setValuesForKeys(datasnapshot.value as! [String:AnyObject])

            

            cell.label_title.text = userModel.userName

            let url = URL(string: userModel.profileImageUrl!)

            URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, err) in

                

                DispatchQueue.main.sync {

                    cell.imageview.image = UIImage(data: data!)

                    cell.imageview.layer.cornerRadius = cell.imageview.frame.width/2

                    cell.imageview.layer.masksToBounds = true

                }

            }).resume()

            

            let lastMessagekey = self.chatrooms[indexPath.row].comments.keys.sorted(){$0>$1}

            cell.label_lastmessage.text = self.chatrooms[indexPath.row].comments[lastMessagekey[0]]?.message

            

        })

        

        return cell

        

        

    }

    override func viewDidAppear(_ animated: Bool) {

        viewDidLoad()

    }

    

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

    

    /*

     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation

     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

     // Get the new view controller using segue.destinationViewController.

     // Pass the selected object to the new view controller.

     }

     */

    

}


class CustomCell: UITableViewCell {

    

    @IBOutlet weak var label_lastmessage: UILabel!

    @IBOutlet weak var imageview: UIImageView!

    @IBOutlet weak var label_title: UILabel!

}















채팅 탭바 클릭하면 채팅 리스트 출력 


//

//  ChatRoomsViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 16..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//




import UIKit

import Firebase


class ChatRoomsViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    @IBOutlet weak var tableview: UITableView!

    

    var uid : String!

    var chatrooms : [ChatModel]! = []

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        self.uid = Auth.auth().currentUser?.uid

        self.getChatroomsList()

        // Do any additional setup after loading the view.

    }

    

    func getChatroomsList(){

        

        Database.database().reference().child("chatrooms").queryOrdered(byChild: "users/"+uid).queryEqual(toValue: true).observeSingleEvent(of: DataEventType.value, with: {(datasnapshot) in

            

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                

                if let chatroomdic = item.value as? [String:AnyObject]{

                    let chatModel = ChatModel(JSON: chatroomdic)

                    self.chatrooms.append(chatModel!)

                }

                

            }

            self.tableview.reloadData()

            

            

        })

        

        

        

    }

    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return self.chatrooms.count

    }

    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "RowCell", for:indexPath)

        

        

        return cell

        

        

    }

    

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

    

    /*

     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation

     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

     // Get the new view controller using segue.destinationViewController.

     // Pass the selected object to the new view controller.

     }

     */

    

}









채팅화면 들어갔을 때 탭바 사라지는 것, 메세지가 화면에서 넘어갈 때 제일 아래 메세지로 화면 내려가는 것 수정, 키보드는 constraint 부분에서 못 찾아서 생략 다음에 찾아서 update 필요


//

//  MainViewController.swift -> PeopleViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 7..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import SnapKit

import Firebase


class PeopleViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {


    var array :  [UserModel] = []

    var tableview : UITableView!

    override func viewDidLoad() {

        super.viewDidLoad()


        tableview = UITableView()

        tableview.delegate = self

        tableview.dataSource = self

        tableview.register(PeopleViewTableCell.self, forCellReuseIdentifier: "Cell")

        view.addSubview(tableview)

        tableview.snp.makeConstraints { (m) in

            m.top.equalTo(view)

            m.bottom.left.right.equalTo(view)

        }

        

            Database.database().reference().child("users").observe(DataEventType.value, with: { (snapshot) in

                

            

                self.array.removeAll()

                

                let myUid = Auth.auth().currentUser?.uid

                

                for child in snapshot.children {

                    let fchild = child as! DataSnapshot

                    let userModel = UserModel()

                    

                    userModel.setValuesForKeys(fchild.value as! [String : Any])

                    

                    if(userModel.uid == myUid){

                        continue

                    }

                        

                    self.array.append(userModel)

                    

                }

                

                DispatchQueue.main.async {

                    self.tableview.reloadData();

                }

                

        })

            

        

        

        // Do any additional setup after loading the view.

    }


    

    

    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return array.count

    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        

        let cell = tableview.dequeueReusableCell(withIdentifier: "Cell", for :indexPath) as! PeopleViewTableCell

        

        let imageview = cell.imageview!

        

        imageview.snp.makeConstraints{(m) in

            m.centerY.equalTo(cell)

            m.left.equalTo(cell).offset(10)

            m.height.width.equalTo(50)

        }

        

        URLSession.shared.dataTask(with: URL(string: array[indexPath.row].profileImageUrl!)!) { (data, response, err) in

            

            DispatchQueue.main.async {

                imageview.image = UIImage(data: data!)

                imageview.layer.cornerRadius = imageview.frame.size.width/2

                imageview.clipsToBounds = true

            }

        }.resume()

        

        let label = cell.label!

        label.snp.makeConstraints{ (m) in

            m.centerY.equalTo(cell)

            m.left.equalTo(imageview.snp.right).offset(20)

        }

        

        label.text = array[indexPath.row].userName

        

        return cell

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return 70

    }

    

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let view = self.storyboard?.instantiateViewController(withIdentifier: "ChatViewController") as? ChatViewController

        view?.destinationUid = self.array[indexPath.row].uid

        self.navigationController?.pushViewController(view!, animated: true)

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}


class PeopleViewTableCell: UITableViewCell{

    

    var imageview: UIImageView! = UIImageView()

    var label: UILabel! = UILabel()

    

    override init(style: UITableViewCellStyle, reuseIdentifier: String?){

        super.init(style: style, reuseIdentifier: reuseIdentifier)

        self.addSubview(imageview)

        self.addSubview(label)

    }

    

    required init?(coder aDecoder: NSCoder) {

        fatalError("init(coder:) has not been implemented")

    }

    

    

}




//

//  ChatViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//



import UIKit

import Firebase


class ChatViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    

    

    

    @IBOutlet weak var tableview: UITableView!

    

    

    @IBOutlet weak var textfield_message: UITextField!

    

    @IBOutlet weak var sendButton: UIButton!

    

    var uid : String?

    var chatRoomUid : String?

    

    var comments : [ChatModel.Comment] = []

    var userModel :UserModel?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        uid = Auth.auth().currentUser?.uid

        sendButton.addTarget(self, action: #selector(createRoom), for: .touchUpInside)

        checkChatRoom()

        self.tabBarController?.tabBar.isHidden = true

        // Do any additional setup after loading the view.

    }

    

    //종료

    override func viewWillDisappear(_ animated: Bool) {

        self.tabBarController?.tabBar.isHidden = false

    }

    

    func keyboardWillShow(notification : Notification){


        UIView.animate(withDuration: 0 , animations: {

            self.view.layoutIfNeeded()

        }, completion: {

            (complete) in

            

            if self.comments.count > 0 {

                self.tableview.scrollToRow(at: IndexPath(item: self.comments.count - 1 , section: 0), at: UITableViewScrollPosition.bottom, animated: true)

            }

        })

    }


        /*

        if let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue{

            self.bottomContraint.constant = keyboardSize.height

 

        

    }

        func keyboardWillHide(notification: Notification){

            self.bottomContraint.constant = 20

            self.view.layoutIfNeeded()

        }

 

 

 */

        


    


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return comments.count

    }

    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        

        if(self.comments[indexPath.row].uid == uid){

            let view = tableView.dequeueReusableCell(withIdentifier: "MyMessageCell", for: indexPath) as! MyMessageCell

            view.label_message.text = self.comments[indexPath.row].message

            view.label_message.numberOfLines = 0

            return view

            

        }else{

            

            let view = tableView.dequeueReusableCell(withIdentifier: "DestinationMessageCell", for: indexPath) as! DestinationMessageCell

            view.label_name.text = userModel?.userName

            view.label_message.text = self.comments[indexPath.row].message

            view.label_message.numberOfLines = 0;

            

            let url = URL(string:(self.userModel?.profileImageUrl)!)

            URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, err) in

                

                DispatchQueue.main.async {

                    

                    view.imageview_profile.image = UIImage(data: data!)

                    view.imageview_profile.layer.cornerRadius = view.imageview_profile.frame.width/2

                    view.imageview_profile.clipsToBounds = true

                    

                }

            }).resume()

            return view

            

        }

        

        return UITableViewCell()

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return UITableViewAutomaticDimension

    }

    

    

    

    

    public var destinationUid :String? // 나중에 내가 채팅할 대상의 uid

  

    

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

    @objc func createRoom(){

        let createRoomInfo : Dictionary<String,Any> = [ "users" : [

            uid!: true,

            destinationUid! :true

            ]

        ]

        

        

        if(chatRoomUid == nil){

            self.sendButton.isEnabled = false

            // 방 생성 코드

            Database.database().reference().child("chatrooms").childByAutoId().setValue(createRoomInfo, withCompletionBlock: { (err, ref) in

                if(err == nil){

                    self.checkChatRoom()

                }

            })

            

        }else{

            let value :Dictionary<String,Any> = [

                

                "uid" : uid!,

                "message" : textfield_message.text!

            ]

            

            Database.database().reference().child("chatrooms").child(chatRoomUid!).child("comments").childByAutoId().setValue(value, withCompletionBlock: { (err, ref) in

                self.textfield_message.text = ""

            })

        }

        

        

        

        

        

    }

    func checkChatRoom(){

        

        Database.database().reference().child("chatrooms").queryOrdered(byChild: "users/"+uid!).queryEqual(toValue: true).observeSingleEvent(of: DataEventType.value,with: { (datasnapshot) in

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                

                if let chatRoomdic = item.value as? [String:AnyObject]{

                    

                    let chatModel = ChatModel(JSON: chatRoomdic)

                    if(chatModel?.users[self.destinationUid!] == true){

                        self.chatRoomUid = item.key

                        self.sendButton.isEnabled = true

                        self.getDestinationInfo()

                    }

                }

                

                

                

            }

        })

        

    }

    

    func getDestinationInfo(){

        

        Database.database().reference().child("users").child(self.destinationUid!).observeSingleEvent(of: DataEventType.value, with: { (datasnapshot) in

            self.userModel = UserModel()

            self.userModel?.setValuesForKeys(datasnapshot.value as! [String:Any])

            self.getMessageList()

            

        })

    }

    func getMessageList(){

        

        Database.database().reference().child("chatrooms").child(self.chatRoomUid!).child("comments").observe(DataEventType.value, with: { (datasnapshot) in

            self.comments.removeAll()

            

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                let comment = ChatModel.Comment(JSON: item.value as! [String:AnyObject])

                self.comments.append(comment!)

            }

            self.tableview.reloadData()

            

     

            if self.comments.count > 0{

                self.tableview.scrollToRow(at: IndexPath(item:self.comments.count - 1,section:0), at: UITableViewScrollPosition.bottom, animated: true)

                

            }

            

       

        })

        

    }

    

    

    

    /*

     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation

     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

     // Get the new view controller using segue.destinationViewController.

     // Pass the selected object to the new view controller.

     }

     */

    

}

   

class MyMessageCell: UITableViewCell{

    

    @IBOutlet weak var label_message: UILabel!

}


class DestinationMessageCell: UITableViewCell{

    

    @IBOutlet weak var imageview_profile: UIImageView!

    @IBOutlet weak var label_message: UILabel!

    @IBOutlet weak var label_name: UILabel!

}












1차적으로 지금까지 코딩한 파일을 전부 게시하겠습니다.


//

//  UserModel.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 9..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit


class UserModel: NSObject {

    

    @objc var profileImageUrl: String?

    @objc var userName: String?

    @objc var uid: String?


}


//

//  ChatModel.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import ObjectMapper


class ChatModel: Mappable {

    

    

    

    @objc public var users :Dictionary<String,Bool> = [:] //채팅방에 참여한 사람들

    public var comments :Dictionary<String,Comment> = [:] //채팅방의 대화내용

    required init?(map: Map) {

        

    }

    func mapping(map: Map) {

        users <- map["users"]

        comments <- map["comments"]

    }

    public class Comment :Mappable{

        @objc public var uid : String?

        @objc public var message : String?

        public required init?(map: Map) {

            

        }

        public  func mapping(map: Map) {

            uid <- map["uid"]

            message <- map["message"]

        }

    }

    

}




//

//  AppDelegate.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 8. 30..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//

import Firebase

import UIKit


@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate {

    

    var window: UIWindow?

    

    

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        // Override point for customization after application launch.

        FirebaseApp.configure()

        return true

    }

    

    func applicationWillResignActive(_ application: UIApplication) {

        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.

    }

    

    func applicationDidEnterBackground(_ application: UIApplication) {

        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.

        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

    }

    

    func applicationWillEnterForeground(_ application: UIApplication) {

        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.

    }

    

    func applicationDidBecomeActive(_ application: UIApplication) {

        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

    }

    

    func applicationWillTerminate(_ application: UIApplication) {

        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

    }

    

    

}





//

//  ViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 8. 30..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import SnapKit

import Firebase


class ViewController: UIViewController {

    

    

    var box = UIImageView()

    var remoteConfig : RemoteConfig!

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        

        remoteConfig = RemoteConfig.remoteConfig()

        let remoteConfigSettings = RemoteConfigSettings(developerModeEnabled: true)

        remoteConfig.configSettings = remoteConfigSettings!

        remoteConfig.setDefaults(fromPlist: "RemoteConfigDefaults")

        

        remoteConfig.fetch(withExpirationDuration: TimeInterval(0)) { (status, error) -> Void in

            if status == .success {

                print("Config fetched!")

                self.remoteConfig.activateFetched()

            } else {

                print("Config not fetched")

                print("Error \(error!.localizedDescription)")

            }

            self.displayWelcome()

        }

        

        

        

        

        self.view.addSubview(box)

        box.snp.makeConstraints { (make) in

            make.center.equalTo(self.view)

        }

        box.image =  imageLiteral(resourceName: "loading_icon")

        

        

    }

    

    func displayWelcome(){

        

        let color = remoteConfig["splash_background"].stringValue

        let caps = remoteConfig["splash_message_caps"].boolValue

        let message = remoteConfig["splash_message"].stringValue

        

        

        if(caps){

            

            let alert = UIAlertController(title: "공지사항", message: message, preferredStyle: UIAlertControllerStyle.alert)

            alert.addAction(UIAlertAction(title: "확인", style: UIAlertActionStyle.default, handler: { (action) in

                exit(0)

            }))

            

            self.present(alert, animated: true, completion: nil)

            

            

        }else{

            

            let loginVC = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController

            

            self.present(loginVC, animated: false, completion: nil)

            

        }

        self.view.backgroundColor = UIColor(hex: color!)

        

        

        

    }

    

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

    

}


extension UIColor {

    convenience init(hex: String) {

        let scanner = Scanner(string: hex)

        

        

        

        scanner.scanLocation = 1

        

        var rgbValue: UInt64 = 0

        

        scanner.scanHexInt64(&rgbValue)

        

        let r = (rgbValue & 0xff0000) >> 16

        let g = (rgbValue & 0xff00) >> 8

        let b = rgbValue & 0xff

        

        self.init(

            red: CGFloat(r) / 0xff,

            green: CGFloat(g) / 0xff,

            blue: CGFloat(b) / 0xff, alpha: 1

        )

    }

}





//

//  LoginViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 5..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import Firebase


class LoginViewController: UIViewController {


    @IBOutlet var email: UITextField!

    @IBOutlet var password: UITextField!

    @IBOutlet var loginButton: UIButton!

    @IBOutlet var signup: UIButton!

    let remoteConfig = RemoteConfig.remoteConfig()

    var color : String!

    override func viewDidLoad() {

        super.viewDidLoad()

        

        try! Auth.auth().signOut()

        let statusBar = UIView()

        self.view.addSubview(statusBar)

        statusBar.snp.makeConstraints {(m) in

            m.right.top.left.equalTo(self.view)

            m.height.equalTo(20)

            

        }

        color = remoteConfig["splash_background"].stringValue

        

        statusBar.backgroundColor = UIColor(hex: color)

        loginButton.backgroundColor = UIColor(hex: color)

        signup.backgroundColor = UIColor(hex: color)

        

        loginButton.addTarget(self, action: #selector(logingEvent), for: .touchUpInside)

        

        Auth.auth().addStateDidChangeListener{(auth, user) in

            if(user != nil){

                let view = self.storyboard?.instantiateViewController(withIdentifier: "MainViewTabBarController") as! UITabBarController

                self.present(view, animated: true, completion: nil)

            }

        }

        

        signup.addTarget(self, action: #selector(presentsSignup), for: .touchUpInside)

        // Do any additional setup after loading the view.

    }

    

    @objc func logingEvent(){

        Auth.auth().signIn(withEmail: email.text!, password: password.text!) {( user, err) in

            if(err != nil) {

                let alert = UIAlertController(title: "에러", message: err.debugDescription, preferredStyle: UIAlertControllerStyle.alert)

                alert.addAction(UIAlertAction(title: "확인",style: UIAlertActionStyle.default, handler: nil))

                self.present(alert, animated: true, completion: nil)

            }

        }

    }

    

    @objc func presentsSignup(){

        let view = self.storyboard?.instantiateViewController(withIdentifier: "SignupViewController") as! SignupViewController

        self.present(view, animated: true, completion: nil)

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


     /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}




//

//  SignupViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 5..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import Firebase


class SignupViewController: UIViewController,UINavigationControllerDelegate,UIImagePickerControllerDelegate {

    

    @IBOutlet var imageView: UIImageView!

    

    @IBOutlet var email: UITextField!

    @IBOutlet var name: UITextField!

    

    @IBOutlet var password: UITextField!

   

    @IBOutlet var signup: UIButton!

    @IBOutlet var cancel: UIButton!

    

    let remoteConfig = RemoteConfig.remoteConfig()

    var color: String?


    override func viewDidLoad() {

        super.viewDidLoad()


        let statusBar = UIView()

        self.view.addSubview(statusBar)

        statusBar.snp.makeConstraints {(m) in

            m.right.top.left.equalTo(self.view)

            m.height.equalTo(20)

        }

        color = remoteConfig["splash_background"].stringValue

        

        statusBar.backgroundColor = UIColor(hex: color!)

        

        

        imageView.isUserInteractionEnabled = true

        imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(imagePicker)))

        

        

        signup.backgroundColor = UIColor(hex: color!)

        cancel.backgroundColor = UIColor(hex: color!)

        

        signup.addTarget(self, action: #selector(signupEvent), for: .touchUpInside)

        cancel.addTarget(self, action: #selector(cancelevent), for: .touchUpInside)

        // Do any additional setup after loading the view.

    }

    @objc func imagePicker(){

        

        let imagePicker = UIImagePickerController()

        imagePicker.delegate = self

        imagePicker.allowsEditing = true

        imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary

        

        self.present(imagePicker, animated: true, completion: nil)

    }

    

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]){

        imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage

        

        dismiss(animated: true, completion: nil)

    }

    

    @objc func signupEvent(){

        Auth.auth().createUser(withEmail: email.text!, password: password.text!) {(user, err) in

            let uid = user?.uid

            

            let image = UIImageJPEGRepresentation(self.imageView.image!, 0.1)

            

            Storage.storage().reference().child("userImages").child(uid!).putData(image!, metadata: nil, completion: { (data, error) in

             

                let imageUrl = data?.downloadURL()?.absoluteString

                let values = ["userName":self.name.text!,"profileImageUrl":imageUrl, "uid":Auth.auth().currentUser?.uid]

                

                Database.database().reference().child("users").child(uid!).setValue(values, withCompletionBlock:

                    { (err, ref) in

                        if(err==nil){

                            self.cancelevent()

                        }

                })

            })

        }

    }

    

    @objc func cancelevent(){

        self.dismiss(animated: true, completion: nil)

    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}




//

//  MainViewController.swift -> PeopleViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 7..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import SnapKit

import Firebase


class PeopleViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {


    var array :  [UserModel] = []

    var tableview : UITableView!

    override func viewDidLoad() {

        super.viewDidLoad()


        tableview = UITableView()

        tableview.delegate = self

        tableview.dataSource = self

        tableview.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")

        view.addSubview(tableview)

        tableview.snp.makeConstraints { (m) in

            m.top.equalTo(view)

            m.bottom.left.right.equalTo(view)

        }

        

            Database.database().reference().child("users").observe(DataEventType.value, with: { (snapshot) in

                

            

                self.array.removeAll()

                

                let myUid = Auth.auth().currentUser?.uid

                

                for child in snapshot.children {

                    let fchild = child as! DataSnapshot

                    let userModel = UserModel()

                    

                    userModel.setValuesForKeys(fchild.value as! [String : Any])

                    

                    if(userModel.uid == myUid){

                        continue

                    }

                        

                    self.array.append(userModel)

                    

                }

                

                DispatchQueue.main.async {

                    self.tableview.reloadData();

                }

                

        })

            

        

        

        // Do any additional setup after loading the view.

    }


    

    

    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return array.count

    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        

        let cell = tableview.dequeueReusableCell(withIdentifier: "Cell", for :indexPath)

        

        let imageview = UIImageView()

        cell.addSubview(imageview)

        imageview.snp.makeConstraints{(m) in

            m.centerY.equalTo(cell)

            m.left.equalTo(cell).offset(10)

            m.height.width.equalTo(50)

        }

        

        URLSession.shared.dataTask(with: URL(string: array[indexPath.row].profileImageUrl!)!) { (data, response, err) in

            

            DispatchQueue.main.async {

                imageview.image = UIImage(data: data!)

                imageview.layer.cornerRadius = imageview.frame.size.width/2

                imageview.clipsToBounds = true

            }

        }.resume()

        

        let label = UILabel()

        cell.addSubview(label)

        label.snp.makeConstraints{ (m) in

            m.centerY.equalTo(cell)

            m.left.equalTo(imageview.snp.right).offset(20)

        }

        

        label.text = array[indexPath.row].userName

        

        return cell

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return 70

    }

    

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let view = self.storyboard?.instantiateViewController(withIdentifier: "ChatViewController") as? ChatViewController

        view?.destinationUid = self.array[indexPath.row].uid

        self.navigationController?.pushViewController(view!, animated: true)

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}







//

//  ChatViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//



import UIKit

import Firebase


class ChatViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    

    

    

    @IBOutlet weak var tableview: UITableView!

    

    

    @IBOutlet weak var textfield_message: UITextField!

    

    @IBOutlet weak var sendButton: UIButton!

    

    var uid : String?

    var chatRoomUid : String?

    

    var comments : [ChatModel.Comment] = []

    var userModel :UserModel?

    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return comments.count

    }

    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        

        if(self.comments[indexPath.row].uid == uid){

            let view = tableView.dequeueReusableCell(withIdentifier: "MyMessageCell", for: indexPath) as! MyMessageCell

            view.label_message.text = self.comments[indexPath.row].message

            view.label_message.numberOfLines = 0

            return view

            

        }else{

            

            let view = tableView.dequeueReusableCell(withIdentifier: "DestinationMessageCell", for: indexPath) as! DestinationMessageCell

            view.label_name.text = userModel?.userName

            view.label_message.text = self.comments[indexPath.row].message

            view.label_message.numberOfLines = 0;

            

            let url = URL(string:(self.userModel?.profileImageUrl)!)

            URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, err) in

                

                DispatchQueue.main.async {

                    

                    view.imageview_profile.image = UIImage(data: data!)

                    view.imageview_profile.layer.cornerRadius = view.imageview_profile.frame.width/2

                    view.imageview_profile.clipsToBounds = true

                    

                }

            }).resume()

            return view

            

        }

        

        return UITableViewCell()

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return UITableViewAutomaticDimension

    }

    

    

    

    

    public var destinationUid :String? // 나중에 내가 채팅할 대상의 uid

    override func viewDidLoad() {

        super.viewDidLoad()

        uid = Auth.auth().currentUser?.uid

        sendButton.addTarget(self, action: #selector(createRoom), for: .touchUpInside)

        checkChatRoom()

        // Do any additional setup after loading the view.

    }

    

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

    @objc func createRoom(){

        let createRoomInfo : Dictionary<String,Any> = [ "users" : [

            uid!: true,

            destinationUid! :true

            ]

        ]

        

        

        if(chatRoomUid == nil){

            self.sendButton.isEnabled = false

            // 방 생성 코드

            Database.database().reference().child("chatrooms").childByAutoId().setValue(createRoomInfo, withCompletionBlock: { (err, ref) in

                if(err == nil){

                    self.checkChatRoom()

                }

            })

            

        }else{

            let value :Dictionary<String,Any> = [

                

                "uid" : uid!,

                "message" : textfield_message.text!

            ]

            

            Database.database().reference().child("chatrooms").child(chatRoomUid!).child("comments").childByAutoId().setValue(value)

        }

        

        

        

        

        

    }

    func checkChatRoom(){

        

        Database.database().reference().child("chatrooms").queryOrdered(byChild: "users/"+uid!).queryEqual(toValue: true).observeSingleEvent(of: DataEventType.value,with: { (datasnapshot) in

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                

                if let chatRoomdic = item.value as? [String:AnyObject]{

                    

                    let chatModel = ChatModel(JSON: chatRoomdic)

                    if(chatModel?.users[self.destinationUid!] == true){

                        self.chatRoomUid = item.key

                        self.sendButton.isEnabled = true

                        self.getDestinationInfo()

                    }

                }

                

                

                

            }

        })

        

    }

    

    func getDestinationInfo(){

        

        Database.database().reference().child("users").child(self.destinationUid!).observeSingleEvent(of: DataEventType.value, with: { (datasnapshot) in

            self.userModel = UserModel()

            self.userModel?.setValuesForKeys(datasnapshot.value as! [String:Any])

            self.getMessageList()

            

        })

    }

    func getMessageList(){

        

        Database.database().reference().child("chatrooms").child(self.chatRoomUid!).child("comments").observe(DataEventType.value, with: { (datasnapshot) in

            self.comments.removeAll()

            

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                let comment = ChatModel.Comment(JSON: item.value as! [String:AnyObject])

                self.comments.append(comment!)

            }

            self.tableview.reloadData()

            

            

            

        })

        

    }

    

    

    

    /*

     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation

     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

     // Get the new view controller using segue.destinationViewController.

     // Pass the selected object to the new view controller.

     }

     */

    

}

   

class MyMessageCell: UITableViewCell{

    

    @IBOutlet weak var label_message: UILabel!

}


class DestinationMessageCell: UITableViewCell{

    

    @IBOutlet weak var imageview_profile: UIImageView!

    @IBOutlet weak var label_message: UILabel!

    @IBOutlet weak var label_name: UILabel!

}




































































//

//  ChatModel.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import ObjectMapper


class ChatModel: Mappable {

    

    

    

    public var users :Dictionary<String,Bool> = [:] //채팅방에 참여한 사람들

    public var comments :Dictionary<String,Comment> = [:] //채팅방의 대화내용

    required init?(map: Map) {

        

    }

    func mapping(map: Map) {

        users <- map["users"]

        comments <- map["comments"]

    }

    public class Comment :Mappable{

        public var uid : String?

        public var message : String?

        public required init?(map: Map) {

            

        }

        public  func mapping(map: Map) {

            uid <- map["uid"]

            message <- map["message"]

        }

    }

    

}



//

//  MainViewController.swift -> PeopleViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 7..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import SnapKit

import Firebase


class PeopleViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {


    var array :  [UserModel] = []

    var tableview : UITableView!

    override func viewDidLoad() {

        super.viewDidLoad()


        tableview = UITableView()

        tableview.delegate = self

        tableview.dataSource = self

        tableview.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")

        view.addSubview(tableview)

        tableview.snp.makeConstraints { (m) in

            m.top.equalTo(view)

            m.bottom.left.right.equalTo(view)

        }

        

            Database.database().reference().child("users").observe(DataEventType.value, with: { (snapshot) in

                

            

                self.array.removeAll()

                

                let myUid = Auth.auth().currentUser?.uid

                

                for child in snapshot.children {

                    let fchild = child as! DataSnapshot

                    let userModel = UserModel()

                    

                    userModel.setValuesForKeys(fchild.value as! [String : Any])

                    

                    if(userModel.uid == myUid){

                        continue

                    }

                        

                    self.array.append(userModel)

                    

                }

                

                DispatchQueue.main.async {

                    self.tableview.reloadData();

                }

                

        })

            

        

        

        // Do any additional setup after loading the view.

    }


    

    

    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return array.count

    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        

        let cell = tableview.dequeueReusableCell(withIdentifier: "Cell", for :indexPath)

        

        let imageview = UIImageView()

        cell.addSubview(imageview)

        imageview.snp.makeConstraints{(m) in

            m.centerY.equalTo(cell)

            m.left.equalTo(cell).offset(10)

            m.height.width.equalTo(50)

        }

        

        URLSession.shared.dataTask(with: URL(string: array[indexPath.row].profileImageUrl!)!) { (data, response, err) in

            

            DispatchQueue.main.async {

                imageview.image = UIImage(data: data!)

                imageview.layer.cornerRadius = imageview.frame.size.width/2

                imageview.clipsToBounds = true

            }

        }.resume()

        

        let label = UILabel()

        cell.addSubview(label)

        label.snp.makeConstraints{ (m) in

            m.centerY.equalTo(cell)

            m.left.equalTo(imageview.snp.right).offset(20)

        }

        

        label.text = array[indexPath.row].userName

        

        return cell

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return 70

    }

    

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let view = self.storyboard?.instantiateViewController(withIdentifier: "ChatViewController") as? ChatViewController

        view?.destinationUid = self.array[indexPath.row].uid

        self.navigationController?.pushViewController(view!, animated: true)

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}







//

//  ChatViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//



import UIKit

import Firebase


class ChatViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    

    

    

    @IBOutlet weak var tableview: UITableView!

    

    

    @IBOutlet weak var textfield_message: UITextField!

    

    @IBOutlet weak var sendButton: UIButton!

    

    var uid : String?

    var chatRoomUid : String?

    

    var comments : [ChatModel.Comment] = []

    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return comments.count

    }

    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        

        let view = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath)

        view.textLabel?.text = self.comments[indexPath.row].message

        

        return view

    }

    

    

    

    

    

    public var destinationUid :String? // 나중에 내가 채팅할 대상의 uid

    override func viewDidLoad() {

        super.viewDidLoad()

        uid = Auth.auth().currentUser?.uid

        sendButton.addTarget(self, action: #selector(createRoom), for: .touchUpInside)

        checkChatRoom()

        // Do any additional setup after loading the view.

    }

    

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

    @objc func createRoom(){

        let createRoomInfo : Dictionary<String,Any> = [ "users" : [

            uid!: true,

            destinationUid! :true

            ]

        ]

        

        

        if(chatRoomUid == nil){

            self.sendButton.isEnabled = false

            // 방 생성 코드

            Database.database().reference().child("chatrooms").childByAutoId().setValue(createRoomInfo, withCompletionBlock: { (err, ref) in

                if(err == nil){

                    self.checkChatRoom()

                }

            })

            

        }else{

            let value :Dictionary<String,Any> = [

                

                "uid" : uid!,

                "message" : textfield_message.text!

            ]

            

            Database.database().reference().child("chatrooms").child(chatRoomUid!).child("comments").childByAutoId().setValue(value)

        }

        

        

        

        

        

    }

    func checkChatRoom(){

        

        Database.database().reference().child("chatrooms").queryOrdered(byChild: "users/"+uid!).queryEqual(toValue: true).observeSingleEvent(of: DataEventType.value,with: { (datasnapshot) in

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                

                if let chatRoomdic = item.value as? [String:AnyObject]{

                    

                    let chatModel = ChatModel(JSON: chatRoomdic)

                    if(chatModel?.users[self.destinationUid!] == true){

                        self.chatRoomUid = item.key

                        self.sendButton.isEnabled = true

                        self.getMessageList()

                    }

                }

                

                

                

            }

        })

        

    }

    func getMessageList(){

        

        Database.database().reference().child("chatrooms").child(self.chatRoomUid!).child("comments").observe(DataEventType.value, with: { (datasnapshot) in

            self.comments.removeAll()

            

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                let comment = ChatModel.Comment(JSON: item.value as! [String:AnyObject])

                self.comments.append(comment!)

            }

            self.tableview.reloadData()

            

            

            

        })

        

    }

    

    

    

    /*

     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation

     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

     // Get the new view controller using segue.destinationViewController.

     // Pass the selected object to the new view controller.

     }

     */

    

}


    





//

//  ChatModel.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit


class ChatModel: NSObject {

    


    public var users: Dictionary<String,Bool> = [:] // 채팅방에 참여한 사람들

    public var comments: Dictionary<String,Comment> = [:] // 채팅방의 대화내용

    

    public class Comment{

        public var uid: String?

        public var message: String?

    }

}




//

//  ChatViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import Firebase


class ChatViewController: UIViewController {


    @IBOutlet var sendButton: UIButton!

    @IBOutlet var textfield_message: UITextField!

    

    var uid: String?

    var chatRoomUid: String?

    

    

    public var destinationUid: String? // 나중에 내가 채팅할 대상의 uid

    override func viewDidLoad() {

        super.viewDidLoad()

        uid = Auth.auth().currentUser?.uid

        sendButton.addTarget(self, action: #selector(createRoom), for: .touchUpInside)

        checkChatRoom()

        // Do any additional setup after loading the view.

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

    @objc func createRoom(){

        let createRoomInfo : Dictionary<String,Any> = [ "users" : [

            uid!: true,

            destinationUid! : true

            ]

        ]

        

        if(chatRoomUid == nil){

        Database.database().reference().child("chatrooms").childByAutoId().setValue(createRoomInfo)

        }else{

            let value: Dictionary<String,Any> = [

                "comments":[

                    "uid" : uid!,

                    "messaage" : textfield_message.text!

                ]

            ]

            Database.database().reference().child("chatrooms").child(chatRoomUid!).child("comments").childByAutoId().setValue(value)

        }

    }

    

    func checkChatRoom(){

        

        Database.database().reference().child("chatrooms").queryOrdered(byChild: "users/"+uid!).queryEqual(toValue:true).observeSingleEvent(of: DataEventType.value,with: {

            (datasnapshot) in

            for item in datasnapshot.children.allObjects as! [DataSnapshot]{

                self.chatRoomUid = item.key

            }

        })

    }


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}









//

//  UserModel.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 9..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit


class UserModel: NSObject {

    

    @objc var profileImageUrl: String?

    @objc var userName: String?

    @objc var uid: String?


}




//

//  ChatModel.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit


class ChatModel: NSObject {

    var uid: String?

    var destinationUid:String?

}




//

//  ChatViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 10..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import Firebase


class ChatViewController: UIViewController {


    @IBOutlet var sendButton: UIButton!

    public var destinationUid: String? // 나중에 내가 채팅할 대상의 uid

    override func viewDidLoad() {

        super.viewDidLoad()


        sendButton.addTarget(self, action: #selector(createRoom), for: .touchUpInside)

        // Do any additional setup after loading the view.

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

    @objc func createRoom(){

        let createRoomInfo = [

            "uid":Auth.auth().currentUser?.uid,

            "destinationUid" : destinationUid

        ]

        

        Database.database().reference().child("chatrooms").childByAutoId().setValue(createRoomInfo)

    }


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}






//

//  SignupViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 5..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import Firebase


class SignupViewController: UIViewController,UINavigationControllerDelegate,UIImagePickerControllerDelegate {

    

    @IBOutlet var imageView: UIImageView!

    

    @IBOutlet var email: UITextField!

    @IBOutlet var name: UITextField!

    

    @IBOutlet var password: UITextField!

   

    @IBOutlet var signup: UIButton!

    @IBOutlet var cancel: UIButton!

    

    let remoteConfig = RemoteConfig.remoteConfig()

    var color: String?


    override func viewDidLoad() {

        super.viewDidLoad()


        let statusBar = UIView()

        self.view.addSubview(statusBar)

        statusBar.snp.makeConstraints {(m) in

            m.right.top.left.equalTo(self.view)

            m.height.equalTo(20)

        }

        color = remoteConfig["splash_background"].stringValue

        

        statusBar.backgroundColor = UIColor(hex: color!)

        

        

        imageView.isUserInteractionEnabled = true

        imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(imagePicker)))

        

        

        signup.backgroundColor = UIColor(hex: color!)

        cancel.backgroundColor = UIColor(hex: color!)

        

        signup.addTarget(self, action: #selector(signupEvent), for: .touchUpInside)

        cancel.addTarget(self, action: #selector(cancelevent), for: .touchUpInside)

        // Do any additional setup after loading the view.

    }

    @objc func imagePicker(){

        

        let imagePicker = UIImagePickerController()

        imagePicker.delegate = self

        imagePicker.allowsEditing = true

        imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary

        

        self.present(imagePicker, animated: true, completion: nil)

    }

    

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]){

        imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage

        

        dismiss(animated: true, completion: nil)

    }

    

    @objc func signupEvent(){

        Auth.auth().createUser(withEmail: email.text!, password: password.text!) {(user, err) in

            let uid = user?.uid

            

            let image = UIImageJPEGRepresentation(self.imageView.image!, 0.1)

            

            Storage.storage().reference().child("userImages").child(uid!).putData(image!, metadata: nil, completion: { (data, error) in

             

                let imageUrl = data?.downloadURL()?.absoluteString

                let values = ["userName":self.name.text!,"profileImageUrl":imageUrl, "uid":Auth.auth().currentUser?.uid]

                

                Database.database().reference().child("users").child(uid!).setValue(values, withCompletionBlock:

                    { (err, ref) in

                        if(err==nil){

                            self.cancelevent()

                        }

                })

            })

        }

    }

    

    @objc func cancelevent(){

        self.dismiss(animated: true, completion: nil)

    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}
















//

//  SignupViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 5..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import Firebase


class SignupViewController: UIViewController,UINavigationControllerDelegate,UIImagePickerControllerDelegate {

    

    @IBOutlet var imageView: UIImageView!

    

    @IBOutlet var email: UITextField!

    @IBOutlet var name: UITextField!

    

    @IBOutlet var password: UITextField!

   

    @IBOutlet var signup: UIButton!

    @IBOutlet var cancel: UIButton!

    

    let remoteConfig = RemoteConfig.remoteConfig()

    var color: String?


    override func viewDidLoad() {

        super.viewDidLoad()


        let statusBar = UIView()

        self.view.addSubview(statusBar)

        statusBar.snp.makeConstraints {(m) in

            m.right.top.left.equalTo(self.view)

            m.height.equalTo(20)

        }

        color = remoteConfig["splash_background"].stringValue

        

        statusBar.backgroundColor = UIColor(hex: color!)

        

        

        imageView.isUserInteractionEnabled = true

        imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(imagePicker)))

        

        

        signup.backgroundColor = UIColor(hex: color!)

        cancel.backgroundColor = UIColor(hex: color!)

        

        signup.addTarget(self, action: #selector(signupEvent), for: .touchUpInside)

        cancel.addTarget(self, action: #selector(cancelevent), for: .touchUpInside)

        // Do any additional setup after loading the view.

    }

    @objc func imagePicker(){

        

        let imagePicker = UIImagePickerController()

        imagePicker.delegate = self

        imagePicker.allowsEditing = true

        imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary

        

        self.present(imagePicker, animated: true, completion: nil)

    }

    

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]){

        imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage

        

        dismiss(animated: true, completion: nil)

    }

    

    @objc func signupEvent(){

        Auth.auth().createUser(withEmail: email.text!, password: password.text!) {(user, err) in

            let uid = user?.uid

            

            let image = UIImageJPEGRepresentation(self.imageView.image!, 0.1)

            

            Storage.storage().reference().child("userImages").child(uid!).putData(image!, metadata: nil, completion: { (data, error) in

             

                let imageUrl = data?.downloadURL()?.absoluteString

                let values = ["userName":self.name.text!,"profileImageUrl":imageUrl]

                

                Database.database().reference().child("users").child(uid!).setValue(values, withCompletionBlock:

                    { (err, ref) in

                        if(err==nil){

                            self.cancelevent()

                        }

                })

            })

        }

    }

    

    @objc func cancelevent(){

        self.dismiss(animated: true, completion: nil)

    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}








//

//  MainViewController.swift -> PeopleViewController.swift

//  FreeTalk

//

//  Created by stayfoolish on 2018. 9. 7..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import SnapKit

import Firebase


class PeopleViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {


    var array :  [UserModel] = []

    var tableview : UITableView!

    override func viewDidLoad() {

        super.viewDidLoad()


        tableview = UITableView()

        tableview.delegate = self

        tableview.dataSource = self

        tableview.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")

        view.addSubview(tableview)

        tableview.snp.makeConstraints { (m) in

            m.top.equalTo(view)

            m.bottom.left.right.equalTo(view)

        }

        

            Database.database().reference().child("users").observe(DataEventType.value, with: { (snapshot) in

                

            

                self.array.removeAll()

                

                for child in snapshot.children {

                    let fchild = child as! DataSnapshot

                    let userModel = UserModel()

                    

                    userModel.setValuesForKeys(fchild.value as! [String : Any])

                    self.array.append(userModel)

                    

                }

                

                DispatchQueue.main.async {

                    self.tableview.reloadData();

                }

                

        })

            

        

        

        // Do any additional setup after loading the view.

    }


    

    

    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return array.count

    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        

        let cell = tableview.dequeueReusableCell(withIdentifier: "Cell", for :indexPath)

        

        let imageview = UIImageView()

        cell.addSubview(imageview)

        imageview.snp.makeConstraints{(m) in

            m.centerY.equalTo(cell)

            m.left.equalTo(cell).offset(10)

            m.height.width.equalTo(50)

        }

        

        URLSession.shared.dataTask(with: URL(string: array[indexPath.row].profileImageUrl!)!) { (data, response, err) in

            

            DispatchQueue.main.async {

                imageview.image = UIImage(data: data!)

                imageview.layer.cornerRadius = imageview.frame.size.width/2

                imageview.clipsToBounds = true

            }

        }.resume()

        

        let label = UILabel()

        cell.addSubview(label)

        label.snp.makeConstraints{ (m) in

            m.centerY.equalTo(cell)

            m.left.equalTo(imageview.snp.right).offset(20)

        }

        

        label.text = array[indexPath.row].userName

        

        return cell

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return 70

    }

    

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let view = self.storyboard?.instantiateViewController(withIdentifier: "ChatViewController")

        self.navigationController?.pushViewController(view!, animated: true)

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}









+ Recent posts