Fail to send Quickblox group chat invitation message - ios

After successfully creating a group QBChatDialog, I try to sent invitation messages to all occupants by
if self.chatDialog.join() == true {
for occupantID in self.chatDialog.occupantIDs {
var inviteMessage = self.createChatNotificationForGroupChatCreation(self.chatDialog)
var timestamp = NSDate().timeIntervalSince1970
inviteMessage.customParameters["date_sent"] = timestamp
// send notification
//
inviteMessage.recipientID = occupantID as! UInt
//QBChat.instance().sendMessage(inviteMessage)
//QBChatDialog. sendMessage(inviteMessage)
if self.chatDialog.sendMessage(inviteMessage) == true {
println("################# Send ok ######################")
} else {
println("!!!!!!!!!!!!!!!! error sending !!!!!!!!!!!!!!!!!!")
}
}
}
but I always get the error. It keeps telling me that "Room is not joined". I did join the room using "self.chatDialog.join()" command. I even check that the process is ok before I send the message. Please help.

Related

How to Get APNS payload from a remote push notification?

I am working on adding Remote push notification support in my OSX application. I can successfully receive the push notification in my PC via apns and when I click the notification banner this is the behavior I am seeing.
If my app is not running , it will launch the application. But never hits on "ReceivedRemoteNotification()". Is this expected behavior ? Is there any way to receive the apns payload in this case ?
If my app is running I get the payload via "ReceivedRemoteNotification" and things are working fine.
So we cannot get apns payload in our app if it is not running?
Any help really appreciated.
thanks,
Jithesh
Figured it out. The payload is available through "NSNotification" parameter of DidFinishLaunching.
public override void DidFinishLaunching(NSNotification notification)
{
var uInfo = notification.UserInfo;
if(uInfo["NSApplicationLaunchUserNotificationKey"] != null)
{
var payLoad = uInfo["NSApplicationLaunchUserNotificationKey"] as NSUserNotification;
if(payLoad.ActivationType == NSUserNotificationActivationType.ActionButtonClicked)
{
NSAlert alert = new NSAlert();
alert.MessageText = "Button Clicked";
alert.RunModal();
}
var userInfo = payLoad.UserInfo;
//not.ActivationType ==
if (userInfo != null && userInfo.ContainsKey(new NSString("aps")))
{
//Get the aps dictionary
NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
if (aps.ContainsKey(new NSString("content")))
{
var deepLink = (aps[new NSString("content")] as NSString).ToString();
NSAlert alert = new NSAlert();
alert.MessageText = deepLink;
alert.RunModal();
//DisplaySubView(deepLink);
//Console.WriteLine($"Deeplink : {deepLink}");
}
}
}

How to fetch the inbox from email agent in swift/objective c using mailcore framework or Any framework?

Step 1: Link (https://github.com/MailCore/MailCore2)
Step 2: I have added mailcore-framework in my project
Step 3: pod install for UICKeyChainStore in my project done
Step 4: Send mail successfully using MCOSMTPSession, MCOMessageBuilder.
Step 5: My problem is that I am not able to fetch using mailcore. Is there any other framework for fetching mail (inbox)?
Sorry for late answer. I have two apps in the App Store, both of them use MailCore2, so I can explain you a thing or two about that.
Of course you can fetch the emails with MailCore2, this is the code. If you have any other doubt with MailCore2 write about that, I will try to find the answer.
var imapsession:MCOIMAPSession = MCOIMAPSession()
func prepareImapSession()
{
// CONFIGURE THAT DEPENDING OF YOUR NEEDS
imapsession.hostname = imapHostname // String
imapsession.username = userName // String
imapsession.password = password // String
imapsession.port = portIMAP // UInt32 number
imapsession.authType = MCOAuthType.saslLogin
imapsession.connectionType = MCOConnectionType.TLS
}
func useImapWithUIDS()
{
// There is more than one option here, explore depending of your needs
let requestKind : MCOIMAPMessagesRequestKind = .headers
let folder : String = "INBOX"
// HERE ALSO EXPLORE DEPENDING OF YOUR NEEDS, RANGE IT IS THE RANGE OF THE UIDS THAT YOU WANT TO FETCH, I SUGGEST TO YOU TO CHANGE THE // NUMBER ONE IF YOU HAVE A LOWER BOUND TO FETCH EMAIL
let uids : MCOIndexSet = MCOIndexSet(range: MCORangeMake(1, UINT64_MAX))
let fetchOperation = imapsession.fetchMessagesOperation(withFolder: folder, requestKind: requestKind, uids: uids)
fetchOperation?.start
{ (err, msg, vanished) -> Void in
if (err != nil)
{
error = err
NSLog((err?.localizedDescription)!)
}
else
{
guard let msgs = msg as? [MCOIMAPMessage]
else
{
print("ERROR GETTING THE MAILS")
return
}
for i in 0..<msgs.count
{
// THE SUBJECT
let subject = msgs[i].header.subject
// THE uid for this email. The uid is unique for one email
let uid = msgs[i].uid
// The sequenceNumber like the nomber say it is the sequence for the emails in the INBOX from the first one // (sequenceNumber = 1) to the last one , it not represent always the same email. Because if you delete one email then //next one will get the sequence number of that email that was deleted
let sequenceNumber = msgs[i].sequenceNumber
}
}
}
// MARK: - EXTRACT THE CONTENT OF ONE EMAIL, IN THIS FUNCTION YOU NEED THE uid, THE UNIQUE NUMBER FOR ONE EMAIL
func useImapFetchContent(uidToFetch uid: UInt32)
{
let operation: MCOIMAPFetchContentOperation = imapsession.fetchMessageOperation(withFolder: "INBOX", uid: uid)
operation.start { (Error, data) in
if (Error != nil)
{
NSLog("ERROR")
return
}
let messageParser: MCOMessageParser = MCOMessageParser(data: data)
// IF YOU HAVE ATTACHMENTS USE THIS
let attachments = messageParser.attachments() as? [MCOAttachment]
// THEN YOU NEED THIS PROPERTIE, IN THIS EXAMPLE I TAKE THI FIRST, USE WHAT EVER YOU WANT
let attachData = attachments?.first?.data
// FOR THE MESSAGEPARSER YOU CAN EPLORE MORE THAN ONE OPTION TO OBTAIN THE TEXT
let msgPlainBody = messageParser.plainTextBodyRendering()
}
You can give https://github.com/snipsco/Postal a try. This is a framework which aims to provide simple access to common email providers.

How to check if PFRelation in Parse contains exactly same array in Swift

I am making a chat Application in ios through parse server. I have made a MessageRoom collection which has many to many relationship with users through PFRelation. Now i am struck . Whenever a user starts a new conversation , I add new entry in MessageRoom collection and use its id in the messages of that group. But when i want to fetch a previous conversation , let say a conversation between 5 users , how will i query the messageRoom which has exactly the same 5 users (not more or less) in its relation ?
This is the code i am using to create or get Message Room . It is not working correctly. What it does is instead of making a new messageRoom first time and fetching the same for latter user , it makes a new messaga room every time.
class func createOrGetMessageRoom(users:[PFUser], description:String)->PFObject{
var returnMessageRoom:PFObject = PFObject(className: PF_MESSAGE_ROOM_CLASS_NAME);
let users = users.sort(increasingIDs)
let query:PFQuery = PFQuery(className: PF_MESSAGE_ROOM_CLASS_NAME)
query.whereKey(PF_MESSAGE_ROOM_USERS, containsAllObjectsInArray : users)
query.findObjectsInBackgroundWithBlock{(objects, error )->Void in
if error == nil {
if objects?.count == 0 {
let messageRoom = PFObject(className: PF_MESSAGE_ROOM_CLASS_NAME)
messageRoom[PF_MESSAGE_ROOM_DESCRIPTION] = description
messageRoom[PF_MESSAGE_ROOM_LAST_USER] = PFUser.currentUser()
messageRoom[PF_MESSAGE_ROOM_LAST_MESSAGE] = ""
messageRoom[PF_MESSAGE_ROOM_COUNTER] = 0
messageRoom[PF_MESSAGE_ROOM_UPDATE_TIME] = NSDate()
let messageUsers = messageRoom.relationForKey(PF_MESSAGE_ROOM_USERS)
for user in users {
messageUsers.addObject(user)
}
messageRoom.saveInBackgroundWithBlock{(success,error)->Void in
if error == nil {
returnMessageRoom = messageRoom
}
}
}else{
returnMessageRoom = objects![0]
}
}else{
print("Message.createMessage Erorr");
print(error)
}
}
return returnMessageRoom
}
class func increasingIDs(user1: PFUser, user2: PFUser) -> Bool {
return user1.objectId < user2.objectId
}
I have also checked this application . What it does is whenever it starts a new chat , it concatenates objectIds of users in ascending order and use it as a groupId which is used for future references and used in chat messages as a foreign key.
It'll work in private chat and in group chat , but what happens if a user has started a group chat , and wants to add new users to this chat ?? If we simple change the group id by concatenating this users id , the previous messages which have used the old group id will no longer appear in this message group.
Also tell me if this approach of making groupID through concatenation is better or many to many relationship is better?
One problem with your function createOrGetMessageRoom is that findObjectsInBackgroundWithBlock is asynchronous, and you're not taking that into account.
What this means is that the findObjectsInBackgroundWithBlock function gets a response a long time after createOrGetMessageRoom has returned.
So, the PFObject you create on the first line of your function is always returned - your function does not wait for findObjectsInBackgroundWithBlock to return a MessageRoom.
To fix this, make your code take a callback like this:
class func createOrGetMessageRoom(users:[PFUser], description:String, callback: (PFObject? -> Void)) {
let users = users.sort(increasingIDs)
let query:PFQuery = PFQuery(className: PF_MESSAGE_ROOM_CLASS_NAME)
query.whereKey(PF_MESSAGE_ROOM_USERS, containsAllObjectsInArray : users)
query.findObjectsInBackgroundWithBlock{(objects, error )->Void in
if error == nil {
if objects?.count == 0 {
let messageRoom = PFObject(className: PF_MESSAGE_ROOM_CLASS_NAME)
messageRoom[PF_MESSAGE_ROOM_DESCRIPTION] = description
messageRoom[PF_MESSAGE_ROOM_LAST_USER] = PFUser.currentUser()
messageRoom[PF_MESSAGE_ROOM_LAST_MESSAGE] = ""
messageRoom[PF_MESSAGE_ROOM_COUNTER] = 0
messageRoom[PF_MESSAGE_ROOM_UPDATE_TIME] = NSDate()
let messageUsers = messageRoom.relationForKey(PF_MESSAGE_ROOM_USERS)
for user in users {
messageUsers.addObject(user)
}
messageRoom.saveInBackgroundWithBlock{(success,error)->Void in
if error == nil {
callback(messageRoom)
}
callback(nil)
}
}else{
callback(objects![0])
}
}else{
print("Message.createMessage Erorr");
print(error)
callback(nil)
}
}
}
Usage:
YourClass.createOrGetMessageRoom([], description: "description") { messageRoom in
// Do something...
}
The db schema in my mind, you should have 3 collections, _User, MessageRoom, and Message.
MessageRoom: users, roomName and other infos.
Message: room(pointer of MessageRoom), msg(content), sender(pointer of _User)
below are pseudo code
In your app, query all current user involved messageRooms.
var query = new Parse.Query("MessageRoom")
query.equalTo("users", currentUser);
//other constraint, roomName, createdAt, limit ...
query.find(...)
Pick a messageRoom object, and then use it to getMessages.
var query2 = new Parse.Query("Message");
query2.eqaulTo("room", roomObj);
query2.include("sender");
query2.descending("createdAt");
query2.find(...)

Quick blox chat message sending response is success but messages are not delivered to server

Just working with Quick blox Chat API though its interesting and fun but stuck horribly when coming to sending messages successfully to group.
I first created a ChatDialog(not public group) and its created with out any problems.Now i want to send messages to the ChatDialog.
This is the code at Client side in Swift :
let user = QBUUser()
user.ID = (QBSession.currentSession().currentUser?.ID)!
user.password = "*********"
QBChat.instance().connectWithUser(user) { (error: NSError?) -> Void in
if error == nil{
print("Success in connection")
self.chatGroup = QBChatDialog(dialogID:self.selectedChatGroup.chatGroupId, type: QBChatDialogType.Group)
self.chatGroup.occupantIDs = self.selectedChatGroup.opponents
self.chatGroup.joinWithCompletionBlock { (err) in
if err == nil{
print("Joined Succesfully")
let message: QBChatMessage = QBChatMessage()
message.text = "PRAISE THE LORD"
message.deliveredIDs = [(QBSession.currentSession().currentUser?.ID)!]
message.readIDs = [(QBSession.currentSession().currentUser?.ID)!]
message.markable = true
self.chatGroup.sendMessage(message, completionBlock: { (error: NSError?) -> Void in
if err == nil{
print(message.text)
print("Message sent Succesfully")
let resPage = QBResponsePage(limit:20, skip: 0)
QBRequest.messagesWithDialogID(self.selectedChatGroup.chatGroupId, extendedRequest: nil, forPage: resPage, successBlock: {(response: QBResponse, messages: [QBChatMessage]?, responcePage: QBResponsePage?) in
print("Messages count is \(messages?.count)")
}, errorBlock: {(response: QBResponse!) in
})
}else{
print(err?.localizedDescription)
}
});
}
else{
print(err?.localizedDescription)
}
}
}
}
This is the Response that i am getting back.i am pretty sure that logging to chat, connecting to group are successful. Even from the response given back from the API is also affirming that sending message is successful.But i am not able to see any messages in the Admin Panel at Quick blox. And also tried getting all the messages from the Chat dialog but its giving 0 messages.So my messages are not getting delivered.
Yah, got the solution from Quickblox API.This is what i missed in my code.
var params = NSMutableDictionary()
params["save_to_history"] = true
message.customParameters = params
Worked like a charm!

PubNub message text returning nil?

When I send a message using iOS to a PubNub channel, I can use the didReceiveMessage function to get that message and put it in my tableView. However, if I send a message via a client in the Dev Dashboard, message.data.message returns nil after I try to cast it as a String. Here's the function in question:
func client(client: PubNub, didReceiveMessage message: PNMessageResult) {
print("Received: %", message.data.message)
let newMessage:String? = message.data.message as? String
print(newMessage) // returns nil
self.messagesArray.append(newMessage!)
dispatch_async(dispatch_get_main_queue()) {
self.messageTableView.reloadData()
}
}
I get the following response in console from print("Received: %", message.data.message):
Received: % Optional({
text = test;
})
However, print(newMessage) is returning nil. What am I doing wrong?
Thanks!
EDIT: I'm getting the same thing when I try to get messages from the historyForChannel function.
//get history
pubNub.historyForChannel("channelname" as String, withCompletion: { (result, status) -> Void in
print(status)
if status == nil {
if result!.data.messages.count > 0 {
let historyMessages = result!.data.messages.description as? [String]
print(result)
for item in historyMessages!{
self.messagesArray.append(item)
}
}
}
})
historyMessages is nil, even though result prints:
Optional({
Operation = History;
Request = {
Authorization = "not set";
Method = GET;
Origin = "pubsub.pubnub.com";
"POST Body size" = 0;
Secure = YES;
URL = "...redacted";
UUID = "...redacted";
};
Response = {
"Processed data" = {
end = 14609023551682481;
messages = (
"technically ",
{
text = "Well..ok then";
},
hi,
"really ",
{
text = "Well..ok then";
},
How do I get the text from these returned messages?
From behaviour and fact what history fetch printed out status object means what you probably configured your client with cipherKey. That status object which you receive probably has category set to decryption error.
If you want to use encryption - you should use same key for all clients, or they won't be able to decrypt sent messages. If cipherKey is set, client automatically try to decrypt data and it will fail if regular text has been received.
Make sure both (console and iOS client) configured with same cipherKey or if you don't need it, make sure what it not set on any of clients.
Best regards,
Sergey.

Resources