Quickblox, chat room does not sends push notification - iphone

I created a chat room in Quickblox, when i sends message to chatroom its offline users does not get any push notification.
To send message :
[[QBChat instance] sendMessage:#"Hey! Did you see last Liverpool match?" toRoom:liverpoolFansRoom];
Is there anything that i am doing wrong or its not enabled on Quickbolx server to sends notification on chatroom's offline users.
Thanx

Push messages does not sends automatically. If you know your recipient user's ID you can send push message manually - you should call method provided below:
[QBMessages TSendPushWithText:#"text"
toUsers:(int)userId
delegate:nil];

Swift 3 :
You can send push notifications for all user connected with the dialog using following code:
var payload = [String:String]()
payload["message"] = message.text!
payload["dialog_id"] = self.dialog.id!
do {
let data = try JSONSerialization.data(withJSONObject: payload, options: .prettyPrinted)
let message = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
var opponentIDs: [String] = []
for userId in self.dialog.occupantIDs! {
// Discard currently logged in user
if userId.uintValue != _user.id {
opponentIDs.append(String(describing: userId))
}
}
let event = QBMEvent()
event.message = message
event.usersIDs = opponentIDs.joined(separator: ",")
event.notificationType = QBMNotificationType.push
event.type = QBMEventType.oneShot
QBRequest.createEvent(event, successBlock: { (response, arrEvents) in
kprint(items: event.name ?? "")
}, errorBlock: { (errRes) in
kprint(items: errRes.error?.description ?? "")
})
} catch {
print(error.localizedDescription)
}

Related

How to listen to Server Side events for Facebook live comments on IOS

I'm using the new SSE endpoints for Live comments on Live videos. my question is how can I achive this on IOS and what library should I use
I tried using the Event Source for IOS https://github.com/inaka/EventSource
But Even though I tried to use OnMessage and addOnEventsource it dosent seem to work.
Here is my code for listening to the live comments
var live_commentURL = URL.init(string:"https://streaming-graph.facebook.com/\(fbLiveStreamId!)/live_comments?access_token=\(accessToken ?? "")&comment_rate=one_per_two_seconds&fields=from{name,id},message")
let queryItems = [NSURLQueryItem(name: "access_token", value: accessToken!), NSURLQueryItem(name: "comment_rate", value: "one_hundred_per_second"),NSURLQueryItem(name: "fields", value: "from{name,id},message")]
let urlComps = NSURLComponents(string: "https://streaming-graph.facebook.com/\(fbLiveStreamId!)/live_comments")!
// var headders:[String:String] = [:]
// headders["access_token"] = accessToken!
// headders["comment_rate"] = "one_hundred_per_second"
// headders["fields"] = "from{name,id},message"
var eventSource = EventSource.init(url:urlComps.url!)
eventSource.connect()
eventSource.onOpen {
print("Successfully Connected to server")
}
eventSource.addEventListener("user-connected") {(id, event, data) in
print("id:", id)
print("event:" , event)
print("data: ", data)
}
eventSource.onMessage { (id, event, data) in
print("id:", id)
print("event:" , event)
print("data: ", data)
}
print(eventSource.events())
eventSource.onComplete { (code, isErro, error) in
print(code)
}
I have tried to send the access tokesn and other fields in headders too but got no luck with it.
I tried 2 methods
method 1
send accesstoken,comment_rateand fields as headders but I dont think that is the right way.
method 2
Since they are all query params I used NSURLComponents.
It was an issue with my auth tokens My bad

How to Queue Up Lots of Inbound CloudKit Notifications

Let's say I save 50 records to CloudKit with a CKModifyRecordsOperation like this:
let operation = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)
operation.savePolicy = .changedKeys
operation.modifyRecordsCompletionBlock = { records, _, error in
//...
}
privateDB.add(operation)
On my other devices, I get sprayed with 50 different background notifications for each CKRecord that changed. That's fine, I expect that.
I process each inbound notification like this:
func processCloudKitNotification(notification: CKNotification, database: CKDatabase){
guard let notification = notification as? CKQueryNotification else { return }
if let recordID = notification.recordID{
var recordIDs = [CKRecordID]()
switch notification.queryNotificationReason {
case .recordDeleted:
//Delete [-]
//...
default:
//Add and Edit [+ /]
recordIDs.append(recordID)
}
let fetchOperation = CKFetchRecordsOperation(recordIDs: recordIDs)
fetchOperation.fetchRecordsCompletionBlock = { records, error in
//...
}
database.add(fetchOperation)
}
}
But since each of the 50 incoming notifications are separate events, this function gets called 50 different times, thus triggering a slew of requests to pull down the full records using the CKRecordIDs that the notifications give me.
How can I queue up all the incoming notification CKRecordIDs within a reasonable period of time so that I can make a more efficient CKFetchRecordsOperation request with more than one recordID at a time?
I ended up using a timer for this, and it works quite well. Basically I start a timer when a new push notification comes in, and I reset it each time an additional notification arrives. Meanwhile, I collect all the CKRecordID's that are coming in and then process them when the timer fires (which happens after the notifications stop flowing in).
Here's my code:
var collectNotificationsTimer: Timer?
var recordIDsFromNotifications = [CKRecordID]()
func processCloudKitNotification(notification: CKNotification, database: CKDatabase){
guard let notification = notification as? CKQueryNotification else { return }
guard let recordID = notification.recordID else { return }
//:: 1 :: Collect record IDs from incoming notifications
if notification.queryNotificationReason == .recordDeleted{
//Delete [-]
//...
}else{
//Add and Edit [+ /]
recordIDsFromNotifications.append(recordID)
//:: 2 :: After collecting IDs for 1 second, request a batch of updated records
collectNotificationsTimer?.invalidate()
collectNotificationsTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false){ _ in
let fetchOperation = CKFetchRecordsOperation(recordIDs: recordIDsFromNotifications)
fetchOperation.fetchRecordsCompletionBlock = { records, error in
recordIDsFromNotifications.removeAll()
if let error = error {
checkCloudKitErrorAndRetryRequest(name: "fetchRecordsCompletionBlock", error: error){}
}else{
if let records = records{
//Save records...
}
}
}
database.add(fetchOperation)
}
}
}

Receipt validation iOS - The file could not be opened because there is no such file

I'm working on a subscription IAP. I set all purchases up, their details come back well, I can do the purchases in sandbox and get all the messages alright. The problem I have now is checking the receipt. I always get a URL returned alright, but when I try to read it I keep getting error that the file does not exist. So I try and refresh with SKReceiptRefreshRequest. Try again, still same.
I have uninstalled app on simulator and two real devices, try again from new install and same problem. One thing I realised, one of the real devices displays the password prompt request with [Sandbox] mention. However after two prompts (including accepting password), instead of purchase completed I get a "user/password don't match" message. On simulator when prompted for itunes account and password it all goes through but the actual purchase confirmation never comes (I waited 4 minutes, stable internet connection).
This is the validation process (I have changed it quite a few times, from different tutorials and other people's problems)
let receiptURL = Bundle.main.appStoreReceiptURL
func receiptValidation() {
print("1")
print("2", receiptURL)
do {
print("3")
let receiptData = try Data(contentsOf: receiptURL!, options: .alwaysMapped)
print(receiptData)
let receiptString = receiptData.base64EncodedString(options: [])
let dict = ["receipt-data" : receiptString, "password" : "\(password)"] as [String : Any]
do {
print("4")
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
if let sandboxURL = Foundation.URL(string:"https://sandbox.itunes.apple.com/verifyReceipt") {
print("5")
var request = URLRequest(url: sandboxURL)
request.httpMethod = "POST"
request.httpBody = jsonData
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: request) { data, response, error in
print("6")
if let receivedData = data,
let httpResponse = response as? HTTPURLResponse,
error == nil,
httpResponse.statusCode == 200 {
print("7")
do {
print("8")
if let jsonResponse = try JSONSerialization.jsonObject(with: receivedData, options: JSONSerialization.ReadingOptions.mutableContainers) as? Dictionary<String, AnyObject> {
print(jsonResponse, jsonResponse.count)
// parse and verify the required informatin in the jsonResponse
} else { print("Failed to cast serialized JSON to Dictionary<String, AnyObject>") }
}
catch { print("Couldn't serialize JSON with error: " + error.localizedDescription) }
}
}
print("51")
task.resume()
} else { print("Couldn't convert string into URL. Check for special characters.") }
}
catch { print("Couldn't create JSON with error: " + error.localizedDescription) }
}
catch {
let appReceiptRefreshRequest = SKReceiptRefreshRequest(receiptProperties: nil)
appReceiptRefreshRequest.delegate = self
appReceiptRefreshRequest.start()
print("Couldn't read receipt data with error: " + error.localizedDescription) }
}
func requestDidFinish(_ request: SKRequest) {
print("???")
do {
let receipt = try Data(contentsOf: receiptURL!) //force unwrap is safe here, control can't land here if receiptURL is nil
print(receipt)
} catch {
print("WTF NO RECEIPT")
// still no receipt, possible but unlikely to occur since this is the "success" delegate method
}
}
And this is the Debugging output from running the app. receiptURL varies between simulator/real device, but other then that everything remains the same.
1
2 Optional(file:///Users/apple/Library/Developer/CoreSimulator/Devices/47EA3293-9B13-4808-BD0B-13D884D14BFE/data/Containers/Data/Application/2F1B7E4E-C523-4270-BF46-6D77F7A2220C/StoreKit/receipt)
3
Couldn't read receipt data with error: The file “receipt” couldn’t be opened because there is no such file.
???
WTF NO RECEIPT
???
WTF NO RECEIPT
Why can't I get the receipt created, or found? Is it a device problem, a bug or am I oblivious to something?
The whole IAP process works asynchronously due to which you will not receive the receipt data unless the whole process has been completed successfully. I can't see the whole code based on what you have pasted in your question above but if you are trying to access the receipt data immediately on the action of a button or something similar, you will not get it.
The correct way to access receipt data is to try accessing the receipt based on success completion handler callback of your IAP request. Once you submit the IAP request there is a server side process which takes care of processing the IAP and then a callback handler from IAP SKPaymentTransactionObserver class is triggered. Using the notification handler from this class you can send the update to your ViewController to check for receipt data.
While further researching, I have found the following article, which solved the problem
article
Important: If you mistakenly use a sandbox tester account to log in to a production environment on your test device instead of your test environment, the sandbox account becomes invalid and can’t be used again. If this happens, create a new sandbox tester account with a new email address.

Send Firebase Swift Push using NSURLSession HTTP Post

I set up my app so that users when they login subscribe to a topic with their user UID. Whenever a user sends a message to another user I will be calling the function below that I am hoping to trigger the push.
func sendPushNotification(toUser: String, message: String) {
let urlString = "https://fcm.googleapis.com/fcm/send"
let topic = "\topic\\(toUser)"
let url = NSURL(string: urlString)!
let paramString = "to=\(topic)"
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)!
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in
do {
if let jsonData = data {
if let jsonDataDict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments) as? [String: AnyObject] {
NSLog("Received data:\n\(jsonDataDict))")
}
}
} catch let err as NSError {
print(err.debugDescription)
}
}
task.resume()
}
Based on Firebase docs I am supposed to do this HTTP request:
Send to a single topic:
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{
"to": "/topics/foo-bar",
"data": {
"message": "This is a Firebase Cloud Messaging Topic Message!",
}
}
I am struggling to see what I pass in the paramString for the message to be sent based off of their example. Also, where do I define the Authorization:key=
Sending a message with Firebase Cloud Messaging requires that you provide your server key in the Authorization header. As the name suggests, this key should only be used in code that runs on an app server (or other infrastructure that you control). Putting the server key into the app that you ship to your users, means malicious users can use it to send messages on your behalf.
From the Firebase documentation on sending messages to topics (emphasis mine):
From the server side, sending messages to a Firebase Cloud Messaging topic is very similar to sending messages to an individual device or to a user group. The app server sets the to key with a value like /topics/yourTopic.

Email Account For MailCore2

I have created a Swift universal app that incorporates the MailCore2 API. It works perfectly on both debug and release mode. When I asked a friend in California to test it out, an alert view popped up with an error message. I found out that the reason for this was because I was using Google as the account I was emailing from.
Here is my code:
var smtpSession = MCOSMTPSession()
smtpSession.hostname = "smtp.gmail.com"
smtpSession.username = "matt#gmail.com"
smtpSession.password = "xxxxxxxxxxxxxxxx"
smtpSession.port = 465
smtpSession.authType = MCOAuthType.SASLPlain
smtpSession.connectionType = MCOConnectionType.TLS
smtpSession.connectionLogger = {(connectionID, type, data) in
if data != nil {
if let string = NSString(data: data, encoding: NSUTF8StringEncoding){
NSLog("Connectionlogger: \(string)")
}
}
}
var builder = MCOMessageBuilder()
builder.header.to = [MCOAddress(displayName: "Rool", mailbox: "itsrool#gmail.com")]
builder.header.from = MCOAddress(displayName: "Matt R", mailbox: "matt#gmail.com")
builder.header.subject = "My message"
builder.htmlBody = "Yo Rool, this is a test message!"
let rfc822Data = builder.data()
let sendOperation = smtpSession.sendOperationWithData(rfc822Data)
sendOperation.start { (error) -> Void in
if (error != nil) {
NSLog("Error sending email: \(error)")
} else {
NSLog("Successfully sent email!")
}
}
Google prevented the email from being sent because it thought a hijacker was trying to access my account (being that I am in a different state when I normally log in.)
My question is: Is there a way of preventing Google from blocking these emails from being sent? I would like people to be able to send emails, no matter where they are located. If this isn't possible, them is there an emailing service that doesn't prevent emails from being sent just because you (the users) are logging in from a different location?
Thanks in advance to all who reply.
this one works for me, hope it works for you too, try this,
let smtpSession:MCOSMTPSession = MCOSMTPSession()
smtpSession.hostname = "smtp.gmail.com"
smtpSession.port = 465
smtpSession.username = "abc#gmail.com"
smtpSession.password = "xxxxx"
smtpSession.authType = MCOAuthType.SASLPlain
smtpSession.connectionType = MCOConnectionType.TLS
let builder:MCOMessageBuilder = MCOMessageBuilder()
let from:MCOAddress = MCOAddress(displayName: "abc", mailbox: "abc#gmail.com")
let to:MCOAddress = MCOAddress(displayName: nil, mailbox: "abc#gmail.com")
builder.header.from = from
builder.header.to = [to]
builder.header.subject = "My Messgae"
builder.htmlBody = "This is test message"
let rcf822Data:NSData = builder.data()
let sendOperation:MCOSMTPSendOperation = smtpSession.sendOperationWithData(rcf822Data)
sendOperation.start { (error:NSError?) in
if (error != nil) {
print("Error Sending Mail : \(error)")
}else{
print("Mail Sent Successfully")
}
}