I'm asking UIApplication.Shared.Open()
method to open default Message App in IOS. I've implemented UserNotification, where and userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { }
method is called, I want to open default Messaging App with this URL.
schemeHere = "sms:/open?addresses=1115555648583&body=lllll"
It works fine for all the states of the application with this static variable. i-e .active .background .inactive
.
The problem arises when through some logic I'm trying to provide an updated value of schemeHere
for every notification.
The program doesn't accepts the updated value. Here is my complete code for preference.
// For handling tap and user actions
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
self.reloadEasy()
//let networkInfo = CTTelephonyNetworkInfo()
//let carrier = networkInfo.subscriberCellularProvider
// Get carrier name
var countryCodeH = ""
if let countryCode = (Locale.current as NSLocale).object(forKey: .countryCode) as? String {
print(countryCode)
countryCodeH = self.phoneCodes[countryCode]!
}
//var numbersH = ""
//var messageH = ""
//var schemeHere = ""
let notifIdentifier = response.notification.request.identifier
print(notifIdentifier)
if notifIdentifier.contains("sms")
{
//open(scheme: schemeHere)
/*
var chrArr = Array(notifIdentifier.characters)
chrArr.removeFirst()
chrArr.removeFirst()
chrArr.removeFirst()
notifIdentifier = String(chrArr)
var fullNameArr = notifIdentifier.characters.split{$0 == "_"}.map(String.init)
let numbers = fullNameArr[1]
messageH = fullNameArr[2]
numbersH.removeAll()
for c in numbers.characters
{
if c != " "
{
numbersH.append(c)
}
}
print(messageH)
print(numbersH)
// "sms:/open?addresses=1-408-555-1212,1-408-555-2121,1-408-555-1221&body=/*message*/"
//sms:/open?addresses=(555)564-8583&body=/*No Bofy*/
schemeHere = "sms:/open?addresses=1" + numbersH + "&body=" + messageH
//schemeHere1-408-555-1212,1-408-555-2121,1-408-555-1221, = "sms:/open?addresses=542-342-3423,23232323&body=/*No Bofy*/"
schemeHere = "sms:/open?addresses=5555648583&body=lllll"
*/
let state: UIApplicationState = UIApplication.shared.applicationState
if state == .active {
self.showMessage(message: "Active \(countryCodeH)")
//let schemeHere = "sms:/open?addresses=1-408-555-1212,1-408-555-2121,1-408-555-1221,92-315-5849537&body=/*message*/"
self.open(notifIdentifier: notifIdentifier)
}
else if state == .background
{
self.showMessage(message: "Background \(countryCodeH)")
self.open(notifIdentifier: notifIdentifier)
}
else if state == .inactive
{
self.showMessage(message: "In-Active \(countryCodeH)")
//let schemeHere = "sms:/open?addresses=14085551212,14085552121,14085551221,923155849537&body=/*message*/"
self.open(notifIdentifier: notifIdentifier)
}
else
{
self.showMessage(message: "Un-defined State \(countryCodeH)")
//let schemeHere = "sms:/open?addresses=14085551212,14085552121,14085551221,923155849537&body=/*message*/"
self.open(notifIdentifier: notifIdentifier)
}
}
}
Here is the function being called.
func open(notifIdentifier: String) {
DispatchQueue.main.async(execute: { () -> Void in
var numbersH = ""
var messageH = ""
var schemeHere = "http://stackoverflow.com/questions/23253175/how-to-tell-if-blocks-in-loop-all-have-completed-executing"
//open(scheme: schemeHere)
var chrArr = Array(notifIdentifier.characters)
chrArr.removeFirst()
chrArr.removeFirst()
chrArr.removeFirst()
let notifIdentifierSecond = String(chrArr)
var fullNameArr = notifIdentifierSecond.characters.split{$0 == "_"}.map(String.init)
let numbers = fullNameArr[1]
messageH = fullNameArr[2]
numbersH.removeAll()
for c in numbers.characters
{
if c != " "
{
numbersH.append(c)
}
}
print(messageH)
print(numbersH)
// "sms:/open?addresses=1-408-555-1212,1-408-555-2121,1-408-555-1221&body=/*message*/"
//sms:/open?addresses=(555)564-8583&body=/*No Bofy*/
schemeHere = "sms:/open?addresses=1" + numbersH + "&body=" + "Wanted to Inform You!"
//schemeHere1-408-555-1212,1-408-555-2121,1-408-555-1221, = "sms:/open?addresses=542-342-3423,23232323&body=/*No Bofy*/"
//sms:/open?addresses=15555648583&body=Wanted to Inform You!
//schemeHere = "sms:/open?addresses=1115555648583&body=lllll"
let deadlineTime = DispatchTime.now() + .seconds(1)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
print(schemeHere)
let when = DispatchTime.now() + 2 // change 2 to desired number of seconds
DispatchQueue.main.asyncAfter(deadline: when) {
// Your code with delay
if let url = URL(string: schemeHere) {
print("Inside URL")
if #available(iOS 10, *) {
print("Now Doing in IOS 10.")
UIApplication.shared.open(url, options: [:],
completionHandler: {
(success) in
print("Open \(schemeHere): \(success)")
})
} else {
let success = UIApplication.shared.openURL(url)
print("Open \(schemeHere): \(success)")
}
}
else
{
print("Inside Scheme!")
print(schemeHere)
}
}
print("test")
}
// UIApplication.shared.open(NSURL(string: schemeHere) as! URL, options: [:], completionHandler: nil)
})
}
After some demonstrated time, I am able to clarify this by doing this in the following way.
Firstly, function open(URL) was called before, so there was a need of putting my code in dependant blocks, i-e using IOS GCD (Grand Central Dispatch).
I've created two functions and putted them in dispatch_Group
.
Here is my code:
// Function A
func functionA_With_Dispatch(identif: String) -> String
{
dispatch_group.enter()
if identif.contains("sms")
{
var numbersH = ""
var messageH = ""
var schemeHere = ""
var chrArr = Array(identif.characters)
chrArr.removeFirst()
chrArr.removeFirst()
chrArr.removeFirst()
let notifIdentifierSecond = String(chrArr)
var fullNameArr = notifIdentifierSecond.characters.split{$0 == "_"}.map(String.init)
let numbers = fullNameArr[1]
messageH = fullNameArr[2]
numbersH.removeAll()
for c in numbers.characters
{
if c != " "
{
numbersH.append(c)
}
}
print(messageH)
print(numbersH)
// "sms:/open?addresses=1-408-555-1212,1-408-555-2121,1-408-555-1221&body=/*message*/"
//sms:/open?addresses=(555)564-8583&body=/*No Bofy*/
schemeHere = "sms:/open?addresses=1" + numbersH + "&body=" + "Wanted to Inform You!"
//schemeHere1-408-555-1212,1-408-555-2121,1-408-555-1221, = "sms:/open?addresses=542-342-3423,23232323&body=/*No Bofy*/"
//sms:/open?addresses=15555648583&body=Wanted to Inform You!
//Open sms:/open?addresses=1115555648583&body=lllll: true
schemeHere = "sms:/open?addresses=\(numbersH)&body=\(messageH)"
print(schemeHere)
dispatch_group.leave()
return schemeHere
}
dispatch_group.leave()
return "empty"
}
Other function for opening URL.
func open_URL_With_Dispatch(schemeHere : String)
{
dispatch_group.enter()
if let url = URL(string: schemeHere) {
print("Inside URL")
if #available(iOS 10, *) {
print("Now Doing in IOS 10.")
UIApplication.shared.open(url, options: [:],
completionHandler: {
(success) in
print("Open \(schemeHere): \(success)")
self.dispatch_group.leave()
})
} else {
let success = UIApplication.shared.openURL(url)
print("Open \(schemeHere): \(success)")
dispatch_group.leave()
}
}
else
{
print("Inside Scheme!")
print(schemeHere)
dispatch_group.leave()
}
}
Now in userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { }
, the work is here.
NOTE: dispatch_group
is declared at the top of the viewController.
dispatch_group = DispatchGroup()
let notifIdentifier = response.notification.request.identifier
self.reloadEasy()
let schemeHere = self.functionA_With_Dispatch(identif: notifIdentifier)
dispatch_group.wait()
/*
switch response.actionIdentifier {
case "action1":
if MFMessageComposeViewController.canSendText() {
print("SMS services are available")
self.sendMessage(recipients: ["243243"], message: "ewhrewuew")
}
else
{
self.showMessage(message: "Can't send sms!")
print("Can't send sms!")
}
default:
if MFMessageComposeViewController.canSendText() {
print("SMS services are available")
self.sendMessage(recipients: ["243243"], message: "ewhrewuew")
}
else
{
self.showMessage(message: "Can't send sms!")
print("Can't send sms!")
}
} // Message Switch
*/
let state: UIApplicationState = UIApplication.shared.applicationState
if state == .active {
self.showMessage(message: "Active")
//let schemeHere = "sms:/open?addresses=1-408-555-1212,1-408-555-2121,1-408-555-1221,92-315-5849537&body=/*message*/"
//self.open(notifIdentifier: notifIdentifier)
self.open_URL_With_Dispatch(schemeHere: schemeHere)
}
else if state == .background
{
self.showMessage(message: "Background")
//self.open(notifIdentifier: notifIdentifier)
self.open_URL_With_Dispatch(schemeHere: schemeHere)
}
else if state == .inactive
{
self.showMessage(message: "In-Active")
//let schemeHere = "sms:/open?addresses=14085551212,14085552121,14085551221,923155849537&body=/*message*/"
//self.open(notifIdentifier: notifIdentifier)
self.open_URL_With_Dispatch(schemeHere: schemeHere)
}
else
{
self.showMessage(message: "Un-defined State")
//let schemeHere = "sms:/open?addresses=14085551212,14085552121,14085551221,923155849537&body=/*message*/"
//self.open(notifIdentifier: notifIdentifier)
self.open_URL_With_Dispatch(schemeHere: schemeHere)
}
Secondly, I've found one other problem after doing so, where I was passing spaces and newLines in the URL string, but now I'm replacing them in the following way for the whole URL.
for c in messageHere.characters
{
if c == " "
{
appendedMessage.append("%20")
}
else if c == "\n"
{
appendedMessage.append("%0A")
}
else
{
appendedMessage.append(c)
}
}