Add function for cancel in UIAlert of Phone Call function - ios

I have a function that places a phone call when a button is pressed.
private func callNumber(phoneNumber:String) {
if let phoneCallURL = URL(string: "tel://\(phoneNumber)") {
let application:UIApplication = UIApplication.shared
if (application.canOpenURL(phoneCallURL)) {
application.open(phoneCallURL, options: [:], completionHandler: nil)
}
}
}
I want to add some functionality if the users hit cancel when the alert pops up to confirm the call. How would I do that?

According to this question: Prompt when trying to dial a phone number using tel:// scheme on iOS 10.3
This alert is actually a bug in iOS 10.3 and should be removed at some point in the future. It isn't supposed to come up for "tel:" links in native apps.
That said, I don't believe there is a way to detect the alert and how the user interacts with it.

Related

iOS - Control over "${App} wants to open ${Another App}" dialog

In my app, I have functionality where the user could open another app lets call it as 'App2'. If App2 is not present on the device, then user will be present with an app not available alert that I created, lets call this as Alert1.
However if App2 is present on the device and user tries to open it, Apple's "${App} wants to open App2" dialog is presented. If user clicks 'Cancel' on this, the callback executes my code to present Alert1.
I don't want my app to display Alert1 when user clicks 'Cancel' on Apple's dialog. Is there a way to control Apple's dialog?
Below is my code:
if let url = urlComponents.url {
UIApplication.shared.open(url, completionHandler: { success in
if !success {
showAppNotAvailableAlert(url.absoluteString, actionLabel: action.label)
}
})
return
}
try
if let url = urlComponents.url {
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, completionHandler: { didURLOpen in
if !didURLOpen {
debugPrint("User pressed cancel button")
}
})
}
else {
showAppNotAvailableAlert(url.absoluteString, actionLabel: action.label)
}
return
}
idea is to check if app exists by using canOpenURL, if it exists then try to open the app and handle error in completion block

Can we make carrier network call by using callkit in swift ios

I am trying to make a phone call from my application for that I want to use callkit, it is possible to make a phone call(non VOIP) over carrier network using callkit? so that I can get the call status and last call time.
I am able to make the voip call and also able to see the call log in phone but didn't found a way to read phone call logs.
Oops unfortunately not, the only thing you can do is to pass the contact no to the default iOS phone app if you want to make a non-voip call
func dialNumber(number : String) {
if let url = URL(string: "tel://\(number)"),
UIApplication.shared.canOpenURL(url) {
if #available(iOS 10, *) {
UIApplication.shared.open(url, options: [:], completionHandler:nil)
} else {
UIApplication.shared.openURL(url)
}
} else {
// add error message here
}
}
Use this function to make a carrier network call using swift 4.

How to detect a call made using openUrl() is ended in ios

In my application, there is an option to make a call when the user taps a phone number. I'm implementing this as shown below:
if let url = URL(string:"tel://\(String(describing: Util.checkForNullString(contactNo)))"), UIApplication.shared.canOpenURL(url){
if #available(iOS 10, *) {
UIApplication.shared.open(url)
} else {
UIApplication.shared.openURL(url)
}
}
I want to do another action soon after the user finishes the call. But how to get notified when the call is finished ?

Force user to update the app programmatically in iOS

In my iOS app I have enabled force app update feature. It is like this.
If there is a critical bug fix. In the server we are setting the new release version. And in splash screen I am checking the current app version and if its lower than the service version, shows a message to update the app.
I have put 2 buttons "Update now", "Update later"
I have 2 questions
If I click now. App should open my app in the appstore with the button UPDATE. Currently I use the link "http://appstore.com/mycompanynamepvtltd"
This opens list of my company apps but it has the button OPEN, not the UPDATE even there is a new update for my app. whats the url to go for update page?
If he click the button "Update Later" is it ok to close the app programmatically? Does this cause to reject my app in the appstore?
Please help me for these 2 questions
Point 2 : You should only allow force update as an option if you don't want user to update later. Closing the app programmatically is not the right option.
Point 1 : You can use a good library available for this purpose.
Usage in Swift:
Library
func applicationDidBecomeActive(application: UIApplication) {
/* Perform daily (.daily) or weekly (.weekly) checks for new version of your app.
Useful if user returns to your app from the background after extended period of time.
Place in applicationDidBecomeActive(_:)*/
Siren.shared.checkVersion(checkType: .daily)
}
Usage in Objective-C: Library
-(void)applicationDidBecomeActive:(UIApplication *)application {
// Perform daily check for new version of your app
[[Harpy sharedInstance] checkVersionDaily];
}
How it works : It used lookup api which returns app details like link including version and compares it.
For an example, look up Yelp Software application by iTunes ID by calling https://itunes.apple.com/lookup?id=284910350
For more info, please visit link
Don't close the app programmatically. Apple can reject the app. Better approach will be do not allow user to use the app. Keep the update button. Either user will go to app store or close the app by himself.
According to Apple, your app should not terminate on its own. Since the user did not hit the Home button, any return to the Home screen gives the user the impression that your app crashed. This is confusing, non-standard behavior and should be avoided.
Please check this forum:
https://forums.developer.apple.com/thread/52767.
It is happening with lot of people. In my project I redirected the user to our website page of downloading app from app store. In that way if the user is not getting update button in app store, at least the user can use the website in safari for the time being.
To specifically answer your question:
Use this URL to directly open to your app in the app store:
https://apps.apple.com/app/id########## where ########## is your app's 10 digit numeric ID. You can find that ID in App Store Connect under the App Information section. It's called "Apple ID".
I actually have terminate functionality built into my app if it becomes so out of date that it can no longer act on the data it receives from the server (my app is an information app that requires connectivity to my web service). My app has not been rejected for having this functionality after a dozen updates over a couple years, although that function has never been invoked. I will be switching to a static message instead of terminating the app, just to be safe to avoid future updates from being rejected.
I have found that the review process is at least somewhat subjective, and different reviewers may focus on different things and reject over something that has previously been overlooked many times.
func appUpdateAvailable() -> (Bool,String?) {
guard let info = Bundle.main.infoDictionary,
let identifier = info["CFBundleIdentifier"] as? String else {
return (false,nil)
}
// let storeInfoURL: String = "http://itunes.apple.com/lookupbundleId=\(identifier)&country=IN"
let storeInfoURL:String = "https://itunes.apple.com/IN/lookup?
bundleId=\(identifier)"
var upgradeAvailable = false
var versionAvailable = ""
// Get the main bundle of the app so that we can determine the app's
version number
let bundle = Bundle.main
if let infoDictionary = bundle.infoDictionary {
// The URL for this app on the iTunes store uses the Apple ID
for the This never changes, so it is a constant
let urlOnAppStore = NSURL(string: storeInfoURL)
if let dataInJSON = NSData(contentsOf: urlOnAppStore! as URL) {
// Try to deserialize the JSON that we got
if let dict: NSDictionary = try?
JSONSerialization.jsonObject(with: dataInJSON as Data, options:
JSONSerialization.ReadingOptions.allowFragments) as! [String:
AnyObject] as NSDictionary? {
if let results:NSArray = dict["results"] as? NSArray {
if let version = (results[0] as! [String:Any]).
["version"] as? String {
// Get the version number of the current version
installed on device
if let currentVersion =
infoDictionary["CFBundleShortVersionString"] as? String {
// Check if they are the same. If not, an
upgrade is available.
print("\(version)")
if version != currentVersion {
upgradeAvailable = true
versionAvailable = version
}
}
}
}
}
}
}
return (upgradeAvailable,versionAvailable)
}
func checkAppVersion(controller: UIViewController){
let appVersion = ForceUpdateAppVersion.shared.appUpdateAvailable()
if appVersion.0 {
alertController(controller: controller, title: "New Update", message: "New version \(appVersion.1 ?? "") is available")
}
}
func alertController(controller:UIViewController,title: String,message: String){
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Update", style: .default, handler: { alert in
guard let url = URL(string: "itms-apps://itunes.apple.com/app/ewap/id1536714073") else { return }
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
}))
DispatchQueue.main.async {
controller.present(alertController, animated: true)
}
}
Use appgrades.io. Keep your app focus on delivering the business value and let 3rd party solution do their tricks. With appgrades, you can, once SDK integrated, create a custom view/alert to display for your old versions users asking them to update their apps. You can customize everything in the restriction view/alert to make it appear as part of your app.

Send button click event from iOS Today Widget without launching the host app

I am writing a Today Widget for an iOS app. The widget has a few action buttons. I want to receive the click event when someone clicks on it. However, it should not launch the app.
I've already tried this but to no avail.
My current implementation is to define a URL Scheme, and call openURL on those button presses like so:
Button 1 links to myApp://button1
Button 2 links to myApp://button2
Button 3 links to myApp://button3
I am receiving these events in the AppDelegate's
application(_:open:options:)
Here's the Code in TodayWodgetController
#IBAction func widgetClicked(sender: UIButton){
if sender == button1 {
let u = NSURL(string: "myApp://button1")
self.extensionContext?.open(u! as URL, completionHandler: nil)
}
...
}
and here is the code I'm using in the host app's AppDelegate
func application(_ app: UIApplication,
open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if url.absoluteString.range(of: "button1") != nil{
print ("Button 1 Pressed")
}
....
return true
}
However, like I said, it also launches the host App. I want it to just send me the click event without launching the App.
Any help would be appreciated.
I don't think there is a way to do that from an app extension.
Definition of open(_ URL: URL, completionHandler: ((Bool) -> Void)? = nil) as described by Apple:
Asks the system open a URL on behalf of the currently running app
extension.
Each extension point determines whether to support this method, or
under which conditions to support this method. In iOS 8, only the
Today extension point (used for creating widgets) supports this
method.
Important: Apple allows a widget to use the open(_:completionHandler:) method to open the widget’s own containing
app.

Resources