How to call `beginRequest` of Call Directory Extension? - ios

I have to test about Call Blocking & Identification. So I followed the steps below.
(1) Create a Call Directory Extension in my project from [File] > [New] > [Target].
(2) Add a logging in Call Directory Extension to test.
class CallDirectoryHandler: CXCallDirectoryProvider {
override func beginRequest(with context: CXCallDirectoryExtensionContext) {
print("test")
}
}
(3) Call reload function of CallKit on my project.
CXCallDirectoryManager.sharedInstance.reloadExtension(withIdentifier: "EXTENSION_BUNDLE_IDENTIFIER", completionHandler: { (error) in
if let error = error {
print(error.localizedDescription)
} else {
print("success")
}
})
(4) Check my app is enabled in Settings > Phone > Call blocking & identification.
And success of 3 is printed, but test of 2 isn't printed.
Is there anything I should check?
Thanks in advance.

I think it is being called correctly as you can check the response on your app target sandbox.
The only way I know to get access to the logs in this case is by going in the Devices window of Xcode and looking at the device console, you should be able to see logs like this:
com.apple.CallKit.CallDirectory: ...
You might also try to debug it by putting directly a breakpoint in this line:
print("test")
Check also tutorials on finding out if you have any issue in the setup between your extension and your app sandboxes, there is a good one here: https://pusher.com/tutorials/callkit-ios-part-1

Related

loadAppContextDataFromInbox error loading in application context from inbox NSFileReadNoPermissionError -> EACCES

I have been developing an app the works with the apple watch's workouts and an iPhone. The app is written in swift and communication has been working properly for weeks while I add features. I am suddenly getting the following error code when I try to run my app on my iPhone.
[WCFileStorage loadAppContextDataFromInbox] error loading in application context from inbox NSFileReadNoPermissionError -> EACCES
This error is being generated on a program that was working fine using the same code. I believe the error is coming from the following line of code:
WCSession.default.updateApplicationContext(dictionary)
in the func shown below.
func sendAppStateToWatch(appState : String?) {
if WCSession.isSupported() {
if let appStatus = appState {
do {
let dictionary = ["iOSAppState" : appStatus]
try WCSession.default.updateApplicationContext(dictionary)
} catch {
print("sendActiveTimeToPhone() ERROR: \(error)")
}
}
}
}
This function has been working without problem for at least a month. Suddenly, I am getting the error shown above. I have rebooted the watch, phone and Xcode without effect. I suspect the error comes from some privacy setting on the phone or watch that flipped, but looking around I cannot find the problem. Any help is appreciated.

How to acknowledge system alerts on a device with KIF testing framework?

I found out how to acknowledge system alerts while on a simulator from this post using this line of code:
self.viewTester.acknowledgeSystemAlert()
Unfortunately, the KIF code has #if TARGET_IPHONE_SIMULATOR wrapped around it, so it won't work on a device. How can I get around permission alerts on a device during automated testing?
I had same issue and here the solution I found:
its right than this KIF function doesn't work on device, its only for simulators! so, You can have a UITest in the UITarget and just a single Test case in it that will add a UIMonitors like this:
// ask for all the permission from users then :
_ = addUIInterruptionMonitor(withDescription: "") { alert -> Bool in
let confirmLabels = ["Allow", "OK"]
for (_, label) in confirmLabels.enumerated() {
let allow = alert.buttons[label]
if allow.exists {
allow.tap()
break
}
}
return true
}
// do some UI interaction here like tapping on some view in app
So you can call this UITest each time before running your UnitTests and that will prepare your app to have all the permissions.
btw, if anyone has better solution please provide cause I wanna know, too ;)

Firebase Database setValue: or removeValue failed: permission_denied iOS

I'm trying to write data to Firebase Database but I keep receiving the following error when my saved button is pressed.
2016-12-02 11:09:42.548 StartupNow[1482:60415] [FirebaseDatabase] setValue: or removeValue: at /test/-KY-VpLZWbp4vjF3BpMk failed: permission_denied
Things I've tried:
I've made sure my .read and .write rules were set to true in my console, reconnected my savedButtonPressed button, and wrote the Firebase reference in a function and called it in my savedButtonPressed() method.
Extra Resource Here is the tutorial I'm following along. https://youtu.be/F42CzqIBxHQ?t=4m14s
var ref: FIRDatabaseReference?
override func viewDidLoad() {
super.viewDidLoad()
ref = FIRDatabase.database().reference()
}
#IBAction func saveButtonPressed() {
// TODO: Post data to Firebase
firebaseChild()
print("********************************")
print("********************************")
}
func firebaseChild () {
ref?.child("Test").childByAutoId().setValue("Hello Firebase")
}
I had a similar issue. It was resolved by resetting the read / write rules for the database. If you changed your rules try reseting them to the default.
Warning: These rules allow anyone to read and write to your database!
Default Rules for Real-time Database
{
"rules": {
".read": true,
".write": true
}
}
Default Rules for Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;
}
}
}
FreddieOh and I chatted over Slack, and the problem was that the database that was listed in the GoogleService-info.plist file didn't match up with the one he was editing. (It looks like maybe in this case, he had deleted and recreated the project in the Firebase console, but hadn't updated the plist file.)
If you find yourself in the same situation where you've set your read and write access to true and are still getting permission denied errors, open up your GoogleService-info.plist file and look at the entry for DATABASE_URL. Then go to the Firebase Database in your project, look at the top of the data tab, and confirm that the URL listed there is the same as the one in your plist file.
I suppose the other thing to check for would be that you updated your database rules to allow global access but forgot to click the Publish button. That... may have happened to me at one point. :)
Go to your Firebase console, and perform following steps which is identify in image.
Please lookup image and follow these steps. If you are beginner and facing problem in image. I make little video about error.
Video Solution :
https://youtu.be/FcQCPqckvqo
Image Solution
I have solved the same issue after trying to use every resource. The only solution is that
Go to fireBase Console -->select your project -->Go to database -->select the Rules("Show in the mid next to the Data")-->make the make both option true
{
"rules": {
".read": true,
".write": true
}
this will be work perfectly
Make sure to select real time database and edit the rule then publish .

How to test if "Allow Full Access" permission is granted from containing app?

I'm working on a keyboard extension project. At some points of the application code I need to test if the user have granted the "Allow Full Access" permission for the keyboard extension. The deal is that I need to do those tests from the application side, and based on this let the user to access keyboard settings or alert him in case the permission wasn't granted.
The problem is that the methods that provided here like:
func isOpenAccessGranted() -> Bool {
return UIPasteboard.generalPasteboard().isKindOfClass(UIPasteboard)
}
or:
func isOpenAccessGranted() -> Bool {
let fm = NSFileManager.defaultManager()
let containerPath = fm.containerURLForSecurityApplicationGroupIdentifier(
"group.com.example")?.path
var error: NSError?
fm.contentsOfDirectoryAtPath(containerPath!, error: &error)
if (error != nil) {
NSLog("Full Access: Off")
return false
}
NSLog("Full Access: On");
return true
}
Working only from the keyboard side, as the keyboard is the only one that is affected from this permission. From the containing app side both of those methods always return true.
Does someone knows a reliable way to test this from the application side?
Consider using NSUSerdefaults in your app and keyboard. In order for an extension and app to be able to share the same NSUserdefaults, you can simply turn on App Groups. Select your main app target under your project in the project navigator and go to capabilities and enable App Groups by toggling it to on, adding your Developer profile and fixing the possibly arising issues.
Now create a new container. According to the help, it must start with “group.”, so give it a name like “group.com.mycompany.myapp”. Select your Today Extension target and repeat this process of switching on app groups. Don’t create a new one, rather select this newly created group to signify that the Today Extension is a part of the group.
This will now allow you to share the same NSUserdefaults as your container app.
All you have to do now is use the code you provided and add the saving method to the NSUserdefaults like so:
func isOpenAccessGranted() -> Bool {
let defaults = NSUserDefaults.standardUserDefaults()
let fm = NSFileManager.defaultManager()
let containerPath = fm.containerURLForSecurityApplicationGroupIdentifier(
"group.com.example")?.path
var error: NSError?
fm.contentsOfDirectoryAtPath(containerPath!, error: &error)
if (error != nil) {
NSLog("Full Access: Off")
defaults.setBool(false, forKey: "hasFullAccess")
return false
}
NSLog("Full Access: On");
defaults.setBool(true, forKey: "hasFullAccess")
return true
}
Do this in your keyboard extension. And then in your parent app, simply retrieve them and act upon their value.
let hasFullAccess : Bool = NSUserDefaults.standardUserDefaults().boolForKey("hasFullAccess")
if hasFullAccess{
//User granted full access
}
else{
//User didn't grant full access
}
If the user didn't grant full access the show an alert, else code away!
EDIT:
After contacting Apple's Technical Developer support they told me that this is not possible to achieve in any supported way as of right now. Their response is below:
Our engineers have reviewed your request and have concluded that there
is no supported way to achieve the desired functionality given the
currently shipping system configurations.
If you would like for Apple to consider adding support for such
features in the future, please submit an enhancement request via the
Bug Reporter tool at https://developer.apple.com/bug-reporting/.
Hope that helps, Julian
You can easily test whether the "Allow Full Access" permission is granted on iOS 11 and later.
To get the "Allow Full Access" permission, first subclass the
UIInputViewController class.
Add the code. The code returns a bool value.
Objective-C
[self hasFullAccess];
Swift
self.hasFullAccess
https://developer.apple.com/documentation/uikit/uiinputviewcontroller/2875763-hasfullaccess?changes=_2
Objective-C
[UIInputViewController new].hasFullAccess;

Google Places Callback not being called in Swift iOS

I am using the GoogleMaps SDK (maps & places). For some reason the following callback is not being called. I have put loggers in there but nothing happens.
var placesClient : GMSPlacesClient?
...
func run(){
self.placesClient?.currentPlaceWithCallback({ (list: GMSPlaceLikelihoodList?, error: NSError?) -> Void in
if let error = error {
println("error: \(error.description)")
return
}
if let list = list {
self.renderList(list)
}
})
}
For some reason the block in currentPlaceWithCallback does not get called. Yesterday it happened because my API had a wrong bundle identifier, after changing which it started working. But today it stopped.
Any idea why this would happen ? Also, are we exposed to any API logs by Google ?
I was getting the same issue on my iPhone 6 device AND iPhone 6 simulator.
The fix was to add the NSLocationWhenInUseUsageDescription permission in Info.plist! But, it worked only on my iPhone 6 device, NOT the simulator.
As mentioned in the Google Place Guide:
(https://developers.google.com/places/ios-api/start)
Please note, as this sample requires access to the location of the device to get the current location, you will need to set the NSLocationWhenInUseUsageDescription key with appropriate explanatory text in your project's Info.plist file. For more details, see the guide to getting current place.
Now, the way I got it working on the iPhone simulator was by changing my location on the Simulator: Debug -> Location. That is, it was set to 'Apple' by default, I just changed it to Bicycle Ride.
It worked for me, may not for all.

Resources