Incorrect sender name showing in chat using MessageKit - swift

I've integrated MessageKit into my project, I'm using MySQL as my db and PHP for my APIs. I've been able to pull messages from the db and display them; but the name of the sender is replaced with the current user that's logged in. I've printed the sender name and it's correct coming over the app correct, but somehow the displayname is not showing the right one. Here is a screenshot with the code below. I've checked the MessageKit instructions and can't figure out what i'm doing wrong.
Member.swift file
internal struct Message: MessageType {
var sender: SenderType
var senderId: String
var messageId: String
var member: String
var id: String?
var content: String
let sentDate: Date
var messagedata: MessageKind {
if let image = image {
return .photo((image as? MediaItem)!)
} else {
return .text(content)
}
}
var image: UIImage? = nil
var downloadURL: URL? = nil
init(messageuser: Sender, content: String) {
sender = Sender(id: meid, displayName: AppSettings.displayName)
self.senderId = meid
self.messageId = uuid
self.member = me
id = nil
self.content = content
sentDate = Date()
self.image = nil
//self.kind = (content as? MessageKind)!
}
init(messageuser: Sender, image: UIImage) {
sender = Sender(id: meid, displayName: AppSettings.displayName)
self.senderId = meid
self.messageId = uuid
self.member = me
id = nil
self.content = ""
sentDate = Date()
self.image = image
}
}
extension Message: Comparable {
static func == (lhs: Message, rhs: Message) -> Bool {
return lhs.id == rhs.id
}
static func < (lhs: Message, rhs: Message) -> Bool {
return lhs.id == rhs.id
}
var kind: MessageKind {
return .text(content)
}
}
DirectMessageViewController
func loadMessages(offset: Int, limit: Int) {
isLoading = true
let me = user!["username"] as! String
let meid = user!["id"] as! String
let uuid = getmessages["uuid"] as! String
print("tell me what the uuid is", uuid)
let url = URL(string: "https://localhost/message.php")
let body = "username=\(me)&uuid=\(uuid)&recipient_id=\(meid)&limit=\(limit)&offset=\(offset)"
var request = URLRequest(url: url!)
request.httpMethod = "POST"
request.httpBody = body.data(using: String.Encoding.utf8)
URLSession.shared.dataTask(with: request) { (data, response, error) in
DispatchQueue.main.async {
if error != nil {
Helper().showAlert(title: "Server Error", message: error!.localizedDescription, in: self)
return
}
do {
guard let data = data else {
Helper().showAlert(title: "Data Error", message: error!.localizedDescription, in: self)
self.isLoading = false
return
}
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary
guard let parseJSON = json else {
print("Error while parsing")
return
}
guard let posts = parseJSON["messages"] as? [NSDictionary] else {
self.isLoading = false
print("Error while parseJSONing")
return
}
self.hhmessages = posts as! [AnyObject?]
for i in 0 ..< self.hhmessages.count {
let sender = Sender(id: (self.hhmessages[i]?["sender_id"])! as! String, displayName: (self.hhmessages[i]?["sender"])! as! String)
let member = self.hhmessages[i]?["recipient"]
print("who's talking", sender as Any)
let text = self.hhmessages[i]?["messagetext"] as? String
let uuid = self.hhmessages[i]?["uuid"]
let sid = self.hhmessages[i]?["sender_id"]
let message_id = self.hhmessages[i]?["notesid"] as? String
let date = self.hhmessages[i]?["date"] as? Date
let message = Message(messageuser: sender, content: text!)
self.messages.append(message)
self.messageList = self.messages
self.messagesCollectionView.reloadData()
self.messagesCollectionView.scrollToBottom()
}
} catch {
Helper().showAlert(title: "JSON Error", message: error.localizedDescription, in: self)
self.isLoading = false
return
}
}
}.resume()
}
}
extension DirectMessageViewController: MessagesDataSource {
func numberOfSections(
in messagesCollectionView: MessagesCollectionView) -> Int {
return messages.count
}
func currentSender() -> SenderType {
return Sender(id: (sender_id as? String)!, displayName: sender.displayName)
}
messageTopLabelAttributedText
func messageTopLabelAttributedText(
for message: MessageType,
at indexPath: IndexPath) -> NSAttributedString? {
return NSAttributedString(
string: message.sender.displayName,
attributes: [.font: UIFont.systemFont(ofSize: 12)])
}
}

Related

No exact matchec incall to instance method 'dataTask'

Hello i have a CollectionViewCell file, where i am trying to call public func configure cell.
Here is func
public func configureCell(with cellViewModel: CellViewModel) {
self.articleTitleLabel.text = cellViewModel.title
if let data = cellViewModel.imageData {
self.articleImage.image = UIImage(data: data)
} else if let url = cellViewModel.urlToImage {
URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
guard let data = data && error == nil else { return }
cellViewModel.imageData = data
DispatchQueue.main.async {
self.articleImage.image = UIImage(data: data)
}
}
}
}
here is model
struct CellViewModel {
let title: String
let urlToImage: String?
let imageData: Data? = nil
init(title: String, urlToImage: String) {
self.title = title
self.urlToImage = urlToImage
}
}
But i got error:
No exact matches in call to instance method 'dataTask'
Why? How can i fix my code?
urlToImage is of type String but the datatask needs an argument of type URL.
You can use:
else if let stringurl = cellViewModel.urlToImage, let url = URL(string: stringurl){

Swift: listen to url property then download photo

I run this code in viewDidLoad, but Profile.currentProfile does not have the photoUrl yet, so it is nil and this code never runs
private func getProfilePicture() {
if let photoURLString = Profile.currentProfile?.photoUrl {
if let photoURL = URL(string: photoURLString) {
if let photoData = try? Data(contentsOf: photoURL) {
self.profilePhotoView.image = UIImage(data: photoData)
self.letsGoButton.isEnabled = true
}
}
} else {
self.profilePhotoView.image = UIImage(named: "default-profile-icon")
}
}
How can I wait until the photoUrl is not nil, then run this code? Thanks
Rik
(edit) this is how profile is set. This is called before the viewController is instantiated.
func copyProfileFieldsFromFB(completionHandler: #escaping ((Error?) -> Void)) {
guard AccessToken.current != nil else { return }
let request = GraphRequest(graphPath: "me",
parameters: ["fields": "email,first_name,last_name,gender, picture.width(480).height(480)"])
request.start(completionHandler: { (_, result, error) in
if let data = result as? [String: Any] {
if let firstName = data["first_name"] {
Profile.currentProfile?.firstName = firstName as? String
}
if let lastName = data["last_name"] {
Profile.currentProfile?.lastName = lastName as? String
}
if let email = data["email"] {
Profile.currentProfile?.email = email as? String
}
if let picture = data["picture"] as? [String: Any] {
if let imageData = picture["data"] as? [String: Any] {
if let url = imageData["url"] as? String {
Profile.currentProfile?.photoUrl = url
}
}
}
}
completionHandler(error)
})
}
Normally, you'll want to use completion handlers to keep track of asynchronous activities. So in your viewDidLoad() you could call something like
Profile.currentProfile?.getPhotoURL { urlString in
if let photoURL = URL(string: photoURLString) {
if let photoData = try? Data(contentsOf: photoURL) {
self.profilePhotoView.image = UIImage(data: photoData)
self.letsGoButton.isEnabled = true
}
}
}
And on your Profile class it would look something like this:
func getPhotoURL(completion: #escaping (urlString) -> Void) {
// get urlString
completion(urlString)
}
You can add private var profileUrl and use didSet observing with it:
... //e.g. your controller
private var profileUrl: URL? {
didSet {
if let url = profileUrl {
getProfilePicture(from: url)// update your func
}
}
}

Parsing get_video_info (YouTube information data) in swift

To get a direct link to YouTube video I made request to get the get_video_info file, in this file that link, but I have to parse it, I find the solution to parse it by PHP but I want to parse it directly from my App
I get the data from my code like this:
let youtubeContentID = "sZz7tiToK1U"
if let infoURL = URL(string:"https://www.youtube.com/get_video_info?video_id=\(youtubeContentID)") {
let request = URLRequest(url: infoURL)
let session = URLSession(configuration: .default)
let task = session.dataTask(with: request, completionHandler: { (data, response, error) -> Void in
if let error = error {
print(error)
} else if let data = data, let result = NSString(data: data, encoding: String.Encoding.utf8.rawValue) {
print(result)
}
})
task.resume()
}
}
I got data with many Ascii symbols like this:
c=WEB&vss_host=s.youtube.com&innertube_api_version=v1&xhr_apiary_host=youtubei.youtube.com&apiary_host_firstparty=&status=ok&t=1&enabled_engage_types=3%2C6%2C4%2C5%2C17%2C1&ssl=1&adaptive_fmts=type%3Dvideo%252Fwebm%253B%2Bcodecs%253D%2522vp9%2522%26eotf%3Dbt709%26projection_type%3D1%26lmt%3D1550114115045036%26bitrate%3D16962786%26size%3D3840x2160%26index%3D221-1771%26quality_label%3D2160p%26xtags%3D%26url%3Dhttps%253A%252F%252Fr2---sn-nuj-wxqek.googlevideo.com%252Fvideoplayback%253Fexpire%253D1551500605%2526usequic%253Dno%2526gir%253Dyes%2526mime%253Dvideo%25252Fwebm%2526requiressl%253Dyes%2526keepalive%253Dyes%2526fvip%253D2%2526clen%253D547103152%2526source%253Dyoutube%2526aitags%253D133%25252C134%25252C135%25252C136%25252C137%25252C160%25252C242%25252C243%25252C244%25252C247%25252C248%25252C271%25252C278%25252C313%25252C394%25252C395%25252C396%25252C397%2526signature%253D9C28A5C103FA95701CD3655795DDB7F2C0954828.55534AC9C7BEE5D644C3A34C2CD4A4EEC9E2FD38%2526lmt%253D1550114115045036%2526ip%253D129.208.30.232%2526key%253Dyt6%2526c%253DWEB%2526ei%253D3bB5XKeFFNWd1wbBpqjgAg%2526txp%253D5531432%2526id%253Do-AIOVogCB8KFe32o_VgxSx-LqaEjNBZxiZ1jl81VTXZhF%2526sparams%253Daitags%25252Cclen%25252Cdur%25252Cei%25252Cgir%25252Cid%25252Cinitcwndbps%25252Cip%25252Cipbits%25252Citag%25252Ckeepalive%25252Clmt%25252Cmime%25252Cmm%25252Cmn%25252Cms%25252Cmv%25252Cpl%25252Crequiressl%25252Csource%25252Cusequic%25252Cexpire%2526initcwndbps%253D296250%2526itag%253D313%2526ms%253Dau%25252Crdu%2526mt%253D1551478917%2526mv%253Dm%2526dur%253D428.933%2526pl%253D19%2526ipbits%253D0%2526mm%253D31%25252C29%2526mn%253Dsn-nuj-wxqek%25252Csn-hgn7yn7l%26clen%3D547103152%26init%3D0-220%26itag%3D313%26primaries%3Dbt709%26fps%3D30%2Ctype%3Dvideo%252Fwebm%253B%2Bcodecs%253D%2522vp9%2522%26eotf%3Dbt709%26projection_type%3D1%26lmt%3D1550113771564979%26bitrate%3D6318874%26size%3D2560x1440%26index%3D220-1763%26quality_label%3D1440p%26xtags%3D%26url%3Dhttps%253A%252F%252Fr2---sn-nuj-wxqek.googlevideo.com%252Fvideoplayback%253Fexpire%253D1551500605%2526usequic%253Dno%2526gir%253Dyes%2526mime%253Dvideo%25252Fwebm%2526requiressl%253Dyes%2526keepalive%253Dyes%2526fvip%253D2%2526clen%253D155020170%2526source%253Dyoutube%2526aitags%253D133%25252C134%25252C135%25252C136%25252C137%25252C160%25252C242%25252C243%25252C244%25252C247%25252C248%25252C271%25252C278%25252C313%25252C394%25252C395%25252C396%25252C397%2526signature%253D4D7BF761EE4A6DFD048DE3D48550FCE80E61B7D0.D625BCC9645471ABA478F79C197B2208F354E15F%2526lmt%253D1550113771564979%2526ip%253D129.208.30.232%2526key%253Dyt6%2526c%253DWEB%2526ei%253D3bB5XKeFFNWd1wbBpqjgAg%2526txp%253D5531432%2526id%253Do-AIOVogCB8KFe32o_VgxSx- .... ext
I find code can deal with this YouTube request, it created on 2015 so it can't run on the new Swift, so I edited it to work on Swift 4, just copy this code in side a new Swift file then call function h264videosWithYoutubeID(youtubeID: your TouTube ID) and you will get the correct url:
import UIKit
public extension NSURL {
func dictionaryForQueryString() -> [String: AnyObject]? {
if let query = self.query {
return query.dictionaryFromQueryStringComponents()
}
let result = absoluteString?.components(separatedBy: "?")
if result!.count > 1 {
return result!.last?.dictionaryFromQueryStringComponents()
}
return nil
}
}
public extension NSString {
func stringByDecodingURLFormat() -> String {
let result = self.replacingOccurrences(of: "+", with: " ")
return result.removingPercentEncoding!
}
func dictionaryFromQueryStringComponents() -> [String: AnyObject] {
var parameters = [String: AnyObject]()
for keyValue in components(separatedBy: "&") {
let keyValueArray = keyValue.components(separatedBy: "=")
if keyValueArray.count < 2 {
continue
}
let key = keyValueArray[0].stringByDecodingURLFormat()
let value = keyValueArray[1].stringByDecodingURLFormat()
parameters[key] = value as AnyObject
}
return parameters
}
}
public class YoutubeUrlReciver: NSObject {
static let infoURL = "http://www.youtube.com/get_video_info?video_id="
static var userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4"
public static func youtubeIDFromYoutubeURL(youtubeURL: NSURL) -> String? {
if let
youtubeHost = youtubeURL.host,
let youtubePathComponents = youtubeURL.pathComponents {
let youtubeAbsoluteString = youtubeURL.absoluteString
if youtubeHost == "youtu.be" as String? {
return youtubePathComponents[1]
} else if youtubeAbsoluteString?.range(of: "www.youtube.com/embed") != nil {
return youtubePathComponents[2]
} else if youtubeHost == "youtube.googleapis.com" ||
youtubeURL.pathComponents!.first == "www.youtube.com" as String? {
return youtubePathComponents[2]
} else if let
queryString = youtubeURL.dictionaryForQueryString(),
let searchParam = queryString["v"] as? String {
return searchParam
}
}
return nil
}
public static func h264videosWithYoutubeID(youtubeID: String) -> [String: AnyObject]? {
let urlString = String(format: "%#%#", infoURL, youtubeID) as String
let url = NSURL(string: urlString)!
let request = NSMutableURLRequest(url: url as URL)
request.timeoutInterval = 5.0
request.setValue(userAgent, forHTTPHeaderField: "User-Agent")
request.httpMethod = "GET"
var responseString = NSString()
let session = URLSession(configuration: URLSessionConfiguration.default)
let group = DispatchGroup()
group.enter()
session.dataTask(with: request as URLRequest, completionHandler: { (data, response, _) -> Void in
if let data = data as NSData? {
responseString = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue)!
}
group.leave()
}).resume()
group.wait()
let parts = responseString.dictionaryFromQueryStringComponents()
if parts.count > 0 {
var videoTitle: String = ""
var streamImage: String = ""
if let title = parts["title"] as? String {
videoTitle = title
}
if let image = parts["iurl"] as? String {
streamImage = image
}
if let fmtStreamMap = parts["url_encoded_fmt_stream_map"] as? String {
// Live Stream
if let _: AnyObject = parts["live_playback"]{
if let hlsvp = parts["hlsvp"] as? String {
return [
"url": "\(hlsvp)" as AnyObject,
"title": "\(videoTitle)" as AnyObject,
"image": "\(streamImage)" as AnyObject,
"isStream": true as AnyObject
]
}
} else {
let fmtStreamMapArray = fmtStreamMap.components(separatedBy: ",")
for videoEncodedString in fmtStreamMapArray {
var videoComponents = videoEncodedString.dictionaryFromQueryStringComponents()
videoComponents["title"] = videoTitle as AnyObject
videoComponents["isStream"] = false as AnyObject
return videoComponents as [String: AnyObject]
}
}
}
}
return nil
}
public static func h264videosWithYoutubeURL(youtubeURL: NSURL,completion: ((
_ videoInfo: [String: AnyObject]?, _ error: NSError?) -> Void)?) {
DispatchQueue.global().async {
if let youtubeID = self.youtubeIDFromYoutubeURL(youtubeURL: youtubeURL), let videoInformation = self.h264videosWithYoutubeID(youtubeID: youtubeID) {
DispatchQueue.main.async {
completion?(videoInformation, nil)
}
}else{
DispatchQueue.main.async {
completion?(nil, NSError(domain: "com.player.youtube.backgroundqueue", code: 1001, userInfo: ["error": "Invalid YouTube URL"]))
}
}
}
}
}

Extra argument 'error' in call in swift

I am new to swift so please treat me as beginner.
I am following tutorial, this is pretty old tutorial and it has used GoogleMap framework whereas I am doing it with pod. In func geocodeAddress in MapTasks.swift file I am getting error called
Extra argument 'error' in call
func geocodeAddress(address: String!, withCompletionHandler completionHandler: ((status: String, success: Bool) -> Void)) {
if let lookupAddress = address {
var geocodeURLString = baseURLGeocode + "address=" + lookupAddress
geocodeURLString = geocodeURLString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let geocodeURL = NSURL(string: geocodeURLString)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let geocodingResultsData = NSData(contentsOfURL: geocodeURL!)
let request = NSMutableURLRequest(URL: geocodingResultsData)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
(let data, let response, let error) in
if let _ = response as? NSHTTPURLResponse {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if error != nil {
print("error=\(error!)")
return
}
if let parseJSON = json {
}
} catch {
print(error)
}
}
}
task.resume()
else {
// Get the response status.
let status = dictionary["status"] as! String
if status == "OK" {
let allResults = dictionary["results"] as! Array<Dictionary<NSObject, AnyObject>>
self.lookupAddressResults = allResults[0]
// Keep the most important values.
self.fetchedFormattedAddress = self.lookupAddressResults["formatted_address"] as! String
let geometry = self.lookupAddressResults["geometry"] as! Dictionary<NSObject, AnyObject>
self.fetchedAddressLongitude = ((geometry["location"] as! Dictionary<NSObject, AnyObject>)["lng"] as! NSNumber).doubleValue
self.fetchedAddressLatitude = ((geometry["location"] as! Dictionary<NSObject, AnyObject>)["lat"] as! NSNumber).doubleValue
completionHandler(status: status, success: true)
}
else {
completionHandler(status: status, success: false)
}
}
})
}
else {
completionHandler(status: "No valid address.", success: false)
}
}
So far I know is I am getting this error because of the diffrent version of swift. Tutorial I am following is written in old version of swift and I am doing it in new
In Swift 2.0, you cannot add 'error' argument in NSJSONSerialization method, you need to use try-catch statement as follows:
func geocodeAddress(address: String!, withCompletionHandler completionHandler: ((status: String, success: Bool) -> Void)) {
if let lookupAddress = address {
var geocodeURLString = baseURLGeocode + "address=" + lookupAddress
geocodeURLString = geocodeURLString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let geocodeURL = NSURL(string: geocodeURLString)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let geocodingResultsData = NSData(contentsOfURL: geocodeURL!)
let request = NSMutableURLRequest(URL: geocodeURL!)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
(let data, let response, let error) in
if let _ = response as? NSHTTPURLResponse {
do {
let dictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if error != nil {
print("error=\(error!)")
return
}
if let parseJSON = dictionary {
let status = dictionary["status"] as! String
if status == "OK" {
let allResults = dictionary["results"] as! Array<Dictionary<NSObject, AnyObject>>
self.lookupAddressResults = allResults[0]
// Keep the most important values.
self.fetchedFormattedAddress = self.lookupAddressResults["formatted_address"] as! String
let geometry = self.lookupAddressResults["geometry"] as! Dictionary<NSObject, AnyObject>
self.fetchedAddressLongitude = ((geometry["location"] as! Dictionary<NSObject, AnyObject>)["lng"] as! NSNumber).doubleValue
self.fetchedAddressLatitude = ((geometry["location"] as! Dictionary<NSObject, AnyObject>)["lat"] as! NSNumber).doubleValue
completionHandler(status: status, success: true)
}
else {
completionHandler(status: status, success: false)
}
}
} catch {
print(error)
}
}
}
task.resume()
})
}
}

My chat data is successfully inserted into firebase, but I cannot fetch the data into designated chat rooms

I am currently following zero2launches chat application, and I also watched/completed their other tutorials on YouTube. While I started the chat application, I thought about changing the chat portion from a tableViewController to JSQMessageViewController. In that effort, I can post the data to firebase, but it won't show up in the individual chat rooms.
Here is the code:
var roomId: String!
var messages = [JSQMessage]()
func observeMessage() {
messageRef.observeEventType(.ChildAdded, withBlock: { snapshot in
//print(snapshot.value)
if let dict = snapshot.value as? [String: AnyObject] {
let mediaType = dict["MediaType"] as! String
let senderId = dict["senderId"] as! String
let senderName = dict["senderName"] as! String
switch mediaType {
case "TEXT":
let text = dict["text"] as? String
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, text: text))
case "PHOTO":
let fileUrl = dict["fileUrl"] as! String
let url = NSURL(string: fileUrl)
let data = NSData(contentsOfURL: url!)
let picture = UIImage(data: data!)
let photo = JSQPhotoMediaItem(image: picture)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
case "VIDEO":
let fileUrl = dict["fileUrl"] as! String
let video = NSURL(string: fileUrl)
let videoItem = JSQVideoMediaItem(fileURL: video, isReadyToPlay: true)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: videoItem))
default:
print("unknow data type")
}
if mediaType == "TEXT" {
let text = dict["text"] as? String
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, text: text))
}else if mediaType == "PHOTO" {
let fileUrl = dict["fileUrl"] as! String
let url = NSURL(string: fileUrl)
let data = NSData(contentsOfURL: url!)
let picture = UIImage(data: data!)
let photo = JSQPhotoMediaItem(image: picture)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
}else if mediaType == "VIDEO" {
let fileUrl = dict["fileUrl"] as! String
let video = NSURL(string: fileUrl)
let videoItem = JSQVideoMediaItem(fileURL: video, isReadyToPlay: true)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: videoItem))
}
print(dict)
let text = dict["text"] as? String
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, text: text))
self.collectionView.reloadData()
}
})
}
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: NSDate!) {
let newMessage = messageRef.childByAutoId()
let messageData = ["text": text, "senderId": senderId, "senderName": senderDisplayName, "MediaType": "TEXT"]
newMessage.setValue(messageData)
}
override func didPressAccessoryButton(sender: UIButton!) {
print("didPressAccessoryButton")
let sheet = UIAlertController(title: "Media Messages", message: "Please select a media", preferredStyle: UIAlertControllerStyle.ActionSheet)
let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) { (alert:UIAlertAction) in
}
let photoLibrary = UIAlertAction(title: "Photo Library", style: UIAlertActionStyle.Default) { (alert: UIAlertAction) in
self.getMediaFrom(kUTTypeImage)
}
let videoLibrary = UIAlertAction(title: "Video Library", style: UIAlertActionStyle.Default) { (alert: UIAlertAction) in
self.getMediaFrom(kUTTypeMovie)
}
sheet.addAction(photoLibrary)
sheet.addAction(videoLibrary)
sheet.addAction(cancel)
self.presentViewController(sheet, animated: true, completion: nil)
}
func getMediaFrom(type: CFString) {
print(type)
let mediaPicker = UIImagePickerController()
mediaPicker.delegate = self
mediaPicker.mediaTypes = [type as String]
self.presentViewController(mediaPicker, animated: true, completion: nil)
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
return messages[indexPath.item]
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let bubbleFactory = JSQMessagesBubbleImageFactory()
return bubbleFactory.outgoingMessagesBubbleImageWithColor(.blackColor())
}
override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("number of item:\(messages.count)" )
return messages.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! JSQMessagesCollectionViewCell
return cell
}
override func collectionView(collectionView: JSQMessagesCollectionView!, didTapMessageBubbleAtIndexPath indexPath: NSIndexPath!) {
print("didTapMessageBubbleAtIndexPath: \(indexPath.item)")
let message = messages[indexPath.item]
if message.isMediaMessage {
if let mediaItem = message.media as? JSQVideoMediaItem {
let player = AVPlayer(URL: mediaItem.fileURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.presentViewController(playerViewController, animated: true, completion: nil)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func sendMedia(picture: UIImage?, video: NSURL?) {
print(picture)
FIRStorage.storage().reference()
if let picture = picture {
let filePath = "\(FIRAuth.auth()?.currentUser!)\(NSDate.timeIntervalSinceReferenceDate())"
print(filePath)
let data = UIImageJPEGRepresentation(picture, 0.1)
let metadata = FIRStorageMetadata()
metadata.contentType = "image/jpg"
FIRStorage.storage().reference().child(filePath).putData(data!, metadata: metadata) { (metadata, error) in
if error != nil {
print(error?.localizedDescription)
return
}
let fileUrl = metadata!.downloadURLs![0].absoluteString
let newMessage = self.messageRef.childByAutoId()
let messageData = ["fileUrl": fileUrl, "senderId": self.senderId, "senderName": self.senderDisplayName, "MediaType": "PHOTO"]
newMessage.setValue(messageData)
}
}else if let video = video {
let filePath = "\(FIRAuth.auth()?.currentUser!)\(NSDate.timeIntervalSinceReferenceDate())"
print(filePath)
let data = NSData(contentsOfURL: video)
let metadata = FIRStorageMetadata()
metadata.contentType = "video/mp4"
FIRStorage.storage().reference().child(filePath).putData(data!, metadata: metadata) { (metadata, error) in
if error != nil {
print(error?.localizedDescription)
return
}
let fileUrl = metadata!.downloadURLs![0].absoluteString
let newMessage = self.messageRef.childByAutoId()
let messageData = ["fileUrl": fileUrl, "senderId": self.senderId, "senderName": self.senderDisplayName, "MediaType": "VIDEO"]
newMessage.setValue(messageData)
}
}
}
}
Here is my existing message database functions
let roofRef = FIRDatabase.database().reference()
class DataService {
static let dataService = DataService()
private var _BASE_REF = roofRef
private var _ROOM_REF = roofRef.child("captions")
private var _MESSAGE_REF = roofRef.child("messages")
private var _PEOPLE_REF = roofRef.child("people")
var currentUser: FIRUser? {
return FIRAuth.auth()!.currentUser!
}
var BASE_REF: FIRDatabaseReference {
return _BASE_REF
}
var ROOM_REF: FIRDatabaseReference {
return _ROOM_REF
}
var MESSAGE_REF: FIRDatabaseReference {
return _MESSAGE_REF
}
var PEOPLE_REF: FIRDatabaseReference {
return _PEOPLE_REF
}
var storageRef: FIRStorageReference {
return FIRStorage.storage().reference()
}
var fileUrl: String!
func CreateNewPost(user: FIRUser, caption: String, data: NSData) {
let filePath = "\(user.uid)/\(Int(NSDate.timeIntervalSinceReferenceDate()))"
let metaData = FIRStorageMetadata()
metaData.contentType = "image/jpg"
storageRef.child(filePath).putData(data, metadata: metaData, completion: { (metadata, error) in
if let error = error{
print("Error uploarding: \(error.description)")
return
}
self.fileUrl = metadata!.downloadURLs![0].absoluteString
if let user = FIRAuth.auth()?.currentUser {
let idCaption = self.BASE_REF.child("captions").childByAutoId()
idCaption.setValue(["caption": caption, "thumbnailURLFromStorage": self.storageRef.child(metadata!.path!).description, "filelUrl": self.fileUrl])
}
})
}
func SignUp(username: String, email: String, password: String, data: NSData) {
FIRAuth.auth()?.createUserWithEmail(email, password: password, completion: { (user, error) in
if let error = error {
print(error.localizedDescription)
return
}
let changeRequest = user?.profileChangeRequest()
changeRequest?.displayName = username
changeRequest?.commitChangesWithCompletion({ (error) in
if let error = error {
print(error.localizedDescription)
return
}
})
let filePath = "profileImage/\(user!.uid)"
let metadata = FIRStorageMetadata()
metadata.contentType = "image/jpeg"
self.storageRef.child(filePath).putData(data, metadata: metadata, completion: { (metadata, error) in
if let error = error {
print("\(error.description)")
return
}
self.fileUrl = metadata?.downloadURLs![0].absoluteString
let changeRequestPhoto = user!.profileChangeRequest()
changeRequestPhoto.photoURL = NSURL(string: self.fileUrl)
changeRequestPhoto.commitChangesWithCompletion({ (error) in
if let error = error {
print(error.localizedDescription)
return
}else{
print("profile updated")
}
})
self.PEOPLE_REF.child((user?.uid)!).setValue(["username": username, "email": email, "profileImage": self.storageRef.child((metadata?.path)!).description])
ProgressHUD.showSuccess("Succeeded.")
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.login()
})
})
}
//implement login func
func login(email: String, password: String) {
FIRAuth.auth()?.signInWithEmail(email, password: password, completion: { (user, error) in
if let error = error {
print(error.localizedDescription)
return
}
ProgressHUD.showSuccess("Succeeded")
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.login()
})
}
// Update profile
func SaveProfile(username: String, email: String, data: NSData) {
let user = FIRAuth.auth()?.currentUser!
let filePath = "\(user!.uid)/\(Int(NSDate.timeIntervalSinceReferenceDate()))"
let metaData = FIRStorageMetadata()
metaData.contentType = "image/jpg"
self.storageRef.child(filePath).putData(data, metadata: metaData) { (metaData, error) in
if let error = error {
print("Error uploading: \(error.description)")
return
}
self.fileUrl = metaData!.downloadURLs![0].absoluteString
let changeRequestProfile = user?.profileChangeRequest()
changeRequestProfile?.photoURL = NSURL(string: self.fileUrl)
changeRequestProfile?.displayName = username
changeRequestProfile?.commitChangesWithCompletion({ (error) in
if let error = error {
print(error.localizedDescription)
ProgressHUD.showError("NetWork error")
}else{
}
})
if let user = user {
user.updateEmail(email, completion: { (error) in
if let error = error {
print(error.description)
}else{
print("email update")
}
})
}
ProgressHUD.showSuccess("Saved")
}
}
func CreateNewMessage(userId: String, roomId: String, textMessage: String) {
let idMessage = roofRef.child("messages").childByAutoId()
DataService.dataService.MESSAGE_REF.child(idMessage.key).setValue(["message": textMessage, "senderId": userId])
DataService.dataService.ROOM_REF.child(roomId).child("messages").child(idMessage.key).setValue(true)
}
func fetchMessageFromServer(roomId: String, callback: (FIRDataSnapshot) -> ()) {
DataService.dataService.ROOM_REF.child(roomId).child("messages").observeEventType(.ChildAdded, withBlock: {snapshot -> Void in
DataService.dataService.MESSAGE_REF.child(snapshot.key).observeEventType(.Value, withBlock: {
snap -> Void in
callback(snap)
})
})
}