I am a student learning Swift and am having trouble calling a number from a button call. I researched and found this code below in a couple of different places but there is always an error saying "This app is not allowed to query for scheme tel". Is there something in the Info.plist file that I'm missing for this code to work? Or is there another issue?
#IBAction func call(_ sender: Any) {
let number = URL(string: "tel://" + restaurant.number)
if UIApplication.shared.canOpenURL(number!) {
if #available(iOS 10, *) {
UIApplication.shared.open(number!)
} else {
UIApplication.shared.openURL(number!)
}
}
}
Based on your description, seems you're trying to access a url starting with tel:// which your application is denied access. If you do have access to that domain, access it via your credentials.
Related
I'm trying to get a google sign in button to work with my iOS app, but I'm getting this error here:
Cannot find 'presentingViewController' in scope
This is the code segment:
func handleSignInButton() {
GIDSignIn.sharedInstance.signIn(
with: signInConfig,
presenting: presentingViewController // this is the line with the error,
callback: GIDSignInCallback? = nil) { user, error in
guard let signInUser = user else {
// Inspect error
return
}
// If sign in succeeded, display the app's main content View.
}
}
I've been told I need to migrate the way I am signing in and I found this here:
https://developers.google.com/identity/sign-in/ios/quick-migration-guide
but I'm confused about this part here:
Manually connect GIDSignInButton to a method that calls signInWithConfiguration:presentingViewController:callback: using an IBAction or similar.
Can someone show me how to do this properly? I'm a iOS novice :)
Thanks!
Working my way thru implementing the CKShare functionality of CloudKit.
I Haven manged to get to the part to share a record (via email for example) and also can confirm the user received the invite. The problem is that when user accepts the record then the app pops up but nothing happens. In order to assist here are some key Elements of the app, and please tell me if i am wrong.
1) The application does not require user to login using their Apple ID
2) I am testing the application via a direct built on two different phones (with seperate Apple IDs) when i Connect the phones to the computer with a Cable (aka not using TestFlight yet).
3) I have checked in the CloudkitDashboard and i can see the record that hah been shared and also see that the recored hah been shared, but instead of seeing the user email I sent the invite I see my email and the fact that the record hah been "accepted"
4) I Haven added the CKSharingSupported key in the Info.plist file.
5) The code in the AppDelegate.swift file am using to accept the CKShare is below. I world like to raw your attention to the fact that the string "User Accepted the Share" never gets printed, which makes me think that this part of the code never runs.
func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
print("User Accepted the Share")
let acceptShareOperation: CKAcceptSharesOperation = CKAcceptSharesOperation(shareMetadatas: [cloudKitShareMetadata])
acceptShareOperation.qualityOfService = .userInteractive
acceptShareOperation.perShareCompletionBlock = {meta, share,
error in
print("The Record Share was Accepted")
}
acceptShareOperation.acceptSharesCompletionBlock = {
error in
/// Send your user to where they need to go in your app
let viewController: SNPDetailsViewController = self.window?.rootViewController as! SNPDetailsViewController
viewController.fetchShare(cloudKitShareMetadata)
}
CKContainer(identifier:
cloudKitShareMetadata.containerIdentifier).add(acceptShareOperation)
}
Any insight to guide me where I am wrong, will be much appreciated.
Thank you for your time!
Please see this answer for more context: CloudKit CKShare URL Goes Nowhere
But make sure that:
You specify a fallback URL for your CloudKit Container that redirects to your application.
Inside your app in Xcode, you set up a URL scheme so that custom URLs like yourapp:// open your application and the query parameter from the fallback URL gets passed into userDidAcceptCloudKitShareWith.
After weeks of trial and error, research and LUCK I managed to find out the problem. All tutorials and online solutions relate to the below code in the AppDelegate.swift, to accept a CKShare record:
func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
let acceptShareOperation: CKAcceptSharesOperation = CKAcceptSharesOperation(shareMetadatas: [cloudKitShareMetadata])
acceptShareOperation.qualityOfService = .userInteractive
acceptShareOperation.perShareCompletionBlock = {meta, share,
error in
DispatchQueue.main.async() {
print("The Record Share was Accepted")
}
}
acceptShareOperation.acceptSharesCompletionBlock = {
error in
guard (error == nil) else{
print("Error \(error?.localizedDescription ?? "")")
return
}
let viewController: SNPDetailsViewController = self.window?.rootViewController as! SNPDetailsViewController
viewController.fetchShare(cloudKitShareMetadata)
}
CKContainer(identifier:
cloudKitShareMetadata.containerIdentifier).add(acceptShareOperation)
}
The solution in my case was to add it in the SceneDelegate.swift in the following function:
func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
(add above code)
}
Hope this helps others!
After recaptcha verification, page only returned blank. It did nothing to do next step.
Screen Shot
In your app delegate's application(_:open:options:) method, call Auth.auth().canHandle(url).
For the blank re-captcha page issue I was able to resolve it by doing these 3 things:
1st thing-
Inside the GoogleSerivce-Info.plist file make sure the REVERSED_CLIENT_ID is added to your project via the URL types using this. Follow the first part of the second step there: Add custom URL schemes to your Xcode project (look at the screenshot).
2nd thing-
In the project navigator select the blue project icon
Select Capabilities
Open Background Modes
Select Background fetch
3rd thing-
Before verifying the phone number call PhoneAuthProvider.provider(auth: Auth.auth())
#IBAction func phoneButton(sender: UIButton) {
// ***step 5***
PhoneAuthProvider.provider(auth: Auth.auth())
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumberTextField.text!, uiDelegate: nil) {
(verificationID, error) in
if let error = error {
print(error.localizedDescription)
return
}
guard let verificationId = verificationID else { return }
// do something with verificationID
}
}
On iOS, the appVerificationDisabledForTesting setting has to be set to TRUE before calling verifyPhoneNumber. This is processed without requiring any APNs token or sending silent push notifications in the background, making it easier to test in a simulator. This also disables the reCAPTCHA fallback flow.
Firebase Docs
I face this issue and fix it by adding this code into my AppDelegate.m
- (BOOL) application: (UIApplication *) app
openURL: (NSURL *) url
options: (NSDictionary <UIApplicationOpenURLOptionsKey, id> *)
options {
if ([[FIRAuth auth] canHandleURL: url]) {
return YES;
} else {
// URL not auth related, developer should handle it.
return NO;
}
}
I'm trying to write a macOS app that would connect to already paired the bluetooth phone and retrieves the list of address book entries and call records. This information should be available via standard OBEX interface. I'm relatively new to macOS development (although have enough experience with iOS development) and I have a feeling that I'm doing something wrong on a very basic level.
Here are snippets of my code:
First I'm finding particular paired Bluetooth device by its address
let paired = IOBluetoothDevice.pairedDevices()
let device = paired?.first(where: { (device) -> Bool in
return (device as? IOBluetoothDevice)?.addressString == "some_address"
}) as? IOBluetoothDevice
This actually works fine and I'm getting back valid object. Next, I'm picking up address book service and creating BluetoothOBEXSession for it
let service = device!.getServiceRecord(for: IOBluetoothSDPUUID(uuid32:kBluetoothSDPUUID16ServiceClassPhonebookAccess.rawValue))
let obexSession = IOBluetoothOBEXSession(sdpServiceRecord: service!)
This also works fine, I'm getting proper service object and session is created.
Next step (I would assume) is to create an OBEXFileTransfer session and do something (like checking current directory or retrieving the content of telecom/cch which supposed to have the list of combined outgoing and incoming calls:
let ftp = OBEXFileTransferServices(obexSession: obexSession!)
ftp!.delegate = self
if ftp!.connectToFTPService() == 0 {
NSLog("\(ftp!.currentPath())") // -- empty
ftp!.changeCurrentFolderForward(toPath: "telecom/cch")
NSLog("\(ftp!.currentPath())") // -- empty
ftp!.retrieveFolderListing()
}
I have added the following delegate's method to my view controller (to receive callbacks from OBEX FTS but they never get called:
override func fileTransferServicesRetrieveFolderListingComplete(_ inServices: OBEXFileTransferServices!, error inError: OBEXError, listing inListing: [Any]!) {
NSLog("Listing complete...")
}
override func fileTransferServicesConnectionComplete(_ inServices: OBEXFileTransferServices!, error inError: OBEXError) {
NSLog("Connection complete...")
}
override func fileTransferServicesDisconnectionComplete(_ inServices: OBEXFileTransferServices!, error inError: OBEXError) {
NSLog("Disconnect complete...")
}
override func fileTransferServicesAbortComplete(_ inServices: OBEXFileTransferServices!, error inError: OBEXError) {
NSLog("Abort complete...")
}
What am I doing wrong here?
I also could not find any good Bluetooth examples for macOS either, if somebody has good links, please do share.
I'm building an app for a business and I've run into a dead end. I need a button that will start a phone call to a client's mobile number.
I have this, which is how it should work in Swift 2:
#IBAction func clientMobile(_ sender: AnyObject) {
UIApplication.shared.openURL(self.mobile!)
}
However openURL is deprecated and I don't see any alternative in the intellisense. What is the Swift 3 equivalent of the above line of code?
One other thing, when I run this code I have thee following error:
fatal error: unexpectedly found nil while unwrapping an Optional value
I know the error is related to self.mobile but I'm not sure how to fix it.
Declarations and extra information:
self.mobileis declared and initialised like this:
var mobile : URL?
//inside view will appear
self.mobile = URL(string: "telprompt://" + (self.dog?.client?.mobile)!)
you much check iOS version
guard let number = URL(string: "telprompt://123456789") else { return }
if #available(iOS 10.0, *) {
UIApplication.shared.open(number)
} else {
// Fallback on earlier versions
UIApplication.shared.openURL(number)
}
From the looks of it, you should be checking dog.client.mobile for some invalid characters in the phone number, or even nil (I can't tell if mobile is really optional there, if so you should check for nil before even attempting to launch the call).
Looks like your URL is coming back as nil, and you're trying to pass that to your openURL.
Your phone number should be free of symbols such as ()+-. You can easily remove those using stringByReplacingCharactersInSet (can't remember the exact name in Swift 3 right now.
openURL(:) is deprecated in iOS 10.
The new method is:
- (void)openURL:(NSURL*)url options:(NSDictionary<NSString *, id> *)options
completionHandler:(void (^ __nullable)(BOOL success))completion
Example usage to support both iOS 10 and earlier versions:
// iOS10 check
if (UIApplication.shared.respondsToSelector(#selector(UIApplication.shared.openURL(_:options:completionHandler:))) {
UIApplication.shared.openURL(self.mobile!, options: [:], completionHandler:nil)
} else {
UIApplication.shared.openURL(self.mobile!)
}
(hope this helps, sorry for any errors im on mobile atm)