I've got an SFAuthoizationView I'm using in my app and I'm trying to call the authorize method from my code to prompt the user to authorize if they currently are not authorized.
My issue is that this method does not seem to work!
My code is as follows, where authView is the SFAuthorizationView and authorizeMe is the method that gets called when a button is clicked (and the log message does show, so I know it's getting called).
If the lock is locked the authorize message just returns false and does not seem to prompt the user for a password.
Does anybody know what's up with this?
- (void) mainViewDidLoad {
[authView setDelegate:self];
[authView setString:"Test String"];
[authView setAutoupdate:YES];
}
- (IBAction)authorizeMe:(id)sender {
NSLog(#"Authorizing...");
[authView authorize:authView];
}
- (void)authorizationViewDidAuthorize:(SFAuthorizationView *)view {
self.enabled = YES;
}
- (void)authorizationViewDidDeauthorize:(SFAuthorizationView *)view {
self.enabled = NO;
}
I had this same problem and I've noticed a few things.
In order for the SFAuthorizationView authorize method to interact with the user you MUST set BOTH of these flags when initializing the SFAuthorizationView:
AuthorizationFlags flags = kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights;
[m_authView setFlags:flags];
However, I don't think the SFAuthorizationView was designed to be used this way.
After setting these flags calls to [m_authView updateStatus:m_authView]; cause the user to be prompted for Admin credentials, and if you set [m_authView setAutoupdate:YES]; the user will be randomly prompted for a password and the prompt will not go away when the user click cancel!
I believe the SFAuthorizationView authorize method suppresses user interaction on purpose.
It seems as though there is another method you can call instead of authorize: (void)buttonPressed:(id)sender. This method isn't documented and it will generate compilation warnings, but it does work on 10.6.
I'm guessing #"Test String" is not the name of an authorization right you've registered with the system. The authorization view needs to know what right you're requesting. This document provides an overview about how to do that.
Related
I have a change method on my NEAR AssemblyScript Contract, which I'm calling from my front end (browser) code. The user is already signed in and can read the view methods on the contract. It's only after trying to call the change method that the user is prompted with the NEAR Wallet requesting authorization.
How can I call the change method without receiving the prompt to request permission again?
You can also see some examples here:
basic github.com/Learn-NEAR/starter--near-api-js
advanced github.com/Learn-NEAR/starter--near-api-js
There's basically 2 interfaces here:
// pass the contract name (as you did)
wallet.requestSignIn('dev-1634098284641-40067785396400');
// pass an object with contract and empty list of methods
wallet.requestSignIn({
contractId: 'dev-1634098284641-40067785396400',
methodNames: []
});
// add a list of methods to constrain what you can call
wallet.requestSignIn({
contractId: 'dev-1634098284641-40067785396400',
methodNames: ['write']
});
I'm answering my own question, because I spent some time trying to figure it out.
When I was calling the function requestSignIn() on the wallet, I also had to specify the contract name.
import {
connect,
WalletConnection
} from 'near-api-js';
...
const near = await connect(nearConfig);
const wallet = new WalletConnection(near);
wallet.requestSignIn('dev-xxxx-yyyy'); // Need to pass the correct contract name to be able to call change methods on behalf of the user without requesting permission again
I know the response to this question is "set it in the info.plist" but if I understand the way this works then if the user rejects the permissions you are requesting they don't get prompted again which effectively bricks your app unless you ...write code to check for permissions. Is that right? So I don't know why everyone acts like it's just automatic on iOS. You still have to check for permissions, right?
Assuming I am right, where can I find documentation on how to do it correctly. I checked this (solution was plugin I don't want to use), this (code is too complicated), this (long-winded non-answer), and this plus a few others from google which point to this plugin which I don't want to use. I just want a link to the documentation on how to check and request permissions on iOS. Is there such a link?
What I have looks like this:
private bool HasLocationPermission()
{
return CoreLocation.CLLocationManager.Status == CoreLocation.CLAuthorizationStatus.Authorized ||
CoreLocation.CLLocationManager.Status == CoreLocation.CLAuthorizationStatus.AuthorizedAlways ||
CoreLocation.CLLocationManager.Status == CoreLocation.CLAuthorizationStatus.AuthorizedWhenInUse;
}
but, of course, that is just for the "Location" permission. I don't see any information about what to check for in the LocationManager documentation. There's something about request rational or something? Where can I find how to do this? No plugins please.
If you study the code in the Permissions Plugin you linked to you can pretty easily deduct what you have to do.
In iOS there are 2 different types of location permissions, for either of them to work, you need to set up some descriptions in your Info.plist, which will be shown when prompted the permission dialog.
Set up either NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription depending on your needs. The distinction between this mode is. When in use, is for when occasionally needing location services, i.e. for briefly showing a map. While always is typically for apps needing it to track the users location all the time.
The section in the Info.plist will look something like:
<key>NSLocationWhenInUseUsageDescription</key>
<string>Do you want My App to access your location?</string>
As you've already figured out you can use CoreLocation and CLLocationManager to get the current permission status:
var locationManager = new CLLocationManager();
var status = locationManager.Status;
Status will either be:
NotDetermined - the App doesn't have permission yet or maybe never asked for it.
AuthorizedAlways - if you requested Always location and added the key NSLocationAlwaysUsageDescription.
AuthorizedWhenInUse - if you requested When In Use location and added the key NSLocationWhenInUseUsageDescription
Denied - user said "no thank you"
If you want to request the permission, simply call:
locationManager.RequestAlwaysAuthorization(); // for always
locationManager.RequestWhenInUseAuthorization(); // for when in use
You can listen to Authorization changes with the AuthorizationChanged event:
locationManager.AuthorizationChanged += OnAuthorizationChanged;
The CLAuthorizationChangedEventArgs will provide you the new status. You may want to hook up this even before requesting the permission.
private void OnAuthorizationChanged(object sender, CLAuthorizationChangedEventArgs args)
{
if (args.Status == CLAuthorizationStatus.AuthorizedAlways ||
args.Status == CLAuthorizationStatus.AuthorizedWhenInUse)
{
// all green, you are good to start listening to location changes!
}
}
Now you can start listening to location changes:
locationManager.LocationsUpdated += OnLocationsUpdated;
locationManager.StartUpdatingLocation();
I'm actually on swift 2.3.
Inbound Call works great with CallKit. But OutGoing Call ....
I saw the SpeakerBox project, I do the same things.
But it doesn't work.
To start my call, I used
let handle = CXHandle(type: .PhoneNumber, value: "TOTO")
let startCallAction = CXStartCallAction(callUUID: uuid, handle: handle)
startCallAction.video = video
let transaction = CXTransaction()
transaction.addAction(startCallAction)
requestTransaction(transaction)
After, in SpeakerBox Project, this function is called :
func provider(provider: CXProvider, perform action: CXStartCallAction)
But not in my project. Then, when i hangup, i see : "Call failed".
Do you have an idea ?
Be sure you are configuring your CXProvider and setting its delegate properly. If you do not set the CXProvider's delegate property, the delegate will not receive any actions to perform.
Also, if you see a "Call Failed" UI, this may indicate your app is crashing. I'd check for crash logs or run the app in the debugger.
As far as I can see, SpeakerBox demo does not perform the following provider method:
https://developer.apple.com/documentation/callkit/cxprovider/1930701-reportcall
func reportCall(with UUID: UUID,
endedAt dateEnded: Date?,
reason endedReason: CXCallEndedReason)
- (void)reportCallWithUUID:(NSUUID *)UUID endedAtDate:(nullable NSDate
*)dateEnded reason:(CXCallEndedReason)endedReason;
Which leads to the "Call failed" UI screen being displayed - as CallKit was not given a reason why the call has ended, and it seems that "
CXCallEndedReasonFailed" is assumed by default.
Call "reportCall endedAt" before requesting the CXEndCallAction transaction to remove "Call failed" screen.
Have you added the required permissions to your info.plist?
I am trying to alter the logged in user. I make my changes as usual, and I call:
[[PFUser currentUser] saveInBackgroundWithBlock:^(BOOL succeeded, NSError *PF_NULLABLE_S error){
if(succeeded){
NSLog(#"Saved user successfully.");
}else{
NSLog(#"Unable to save user: %#", error);
}
}];
It saves successfully, but my changes are gone. Just before saving, my user objects has this key:
.meta.acceptsAllMessages = 1. The moment save completion block returns, that key is gone. `(meta is my generic JSON object at user, and other values in meta key are retained with no problem). My changes aren't also reflect to the server side too.
The first suspect was the beforeSave trigger, however there's absolutely nothing related to meta keys in my trigger, so that's not the case. Why would this happen?
UPDATE: There seems to be a problem deeper down. I was saving something else entirely, and ran into the same issue. I've enabled airplane mode, and I wanted to save my current user, and it called the completion handler immediately, with succeeded set to YES and error set to nil without an internet connection. I've double checked that I'm using saveInBackgroundWithBlock: and not saveEventually. Why does this happen?
Okay, I've found the solution.
I was adding an object to the array inside my user object, without assigning the property itself. In the latest instance, I was doing something like:
[[PFUser currentUser][#"myArray"] addObject:#"something"];
[[PFUser currentUser] saveInBackground...];
Because I was not assigning any object itself, [my assumption is that] Parse thought that my user object was not dirty, and it completed immediately without even trying to save. I've solved the problem like this:
NSMutableArray *array = [PFUser currentUser][#"myArray"];
[array addObject:#"something"];
[PFUser currentUser][#"myArray"] = array;
The last line is the key. I'm assigning to the "myArray" field of Parse object, which causes Parse to mark my user dirty. Then, when I save, because it is dirty, it actually saves my user to the server, and it works.
I have inherited some GEB tests that are testing logging into a site (and various error cases/validation warnings).
The test runs through some validation failures and then it attempts to re-navigate to the same page (just to refresh the page/dom) and attempts a valid login. Using GEB's to() method, it detects that you are attempting to navigate to the page you are on, it just calls refresh - the problem here is that attempts to refresh the last POST request, and the driver displays the
"To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier"
message - as the test is not expecting this popup, it hangs and the tests timeout.
Is there a way to turn off these warnings in Firefox webdriver? or to auto-ignore/accept them via Selenium or GEB?
GEB Version: 0.9.2,
Selenium Version: 2.39.0
(Also tried with minor version above: 0.9.3 & 2.40.0)
Caveats:
I know about the POST/Re-direct/GET pattern - but am not at liberty to change the application code in this case
The warning message only causes an issue intermittently (maybe 1 in 5 times) - I have put this down to speed/race conditions whereby the test completes the next actions before the message appears - I know a possible solution is to update tests to wait for message to appear and then accept, but my question is, is there a global setting that can just avoid these being triggered/displayed?
That refresh() is there to work around an issue with IE driver which ignores calls to driver.get() with the same url as the current one.
Instead of monkey patching Browser class (which might bite you somewhere down the line or might not) I would change the url of your login page class. You might for example add an insignificant query string - I think that simply a ? at the end should suffice. The driver.currentUrl == newUrl condition will evaluate to false and you will not see that popup anymore.
If I understand you issue properly this might help. In Groovy you can modify a class on the fly.
We use Spock with Geb and I placed this in a Super class which all Spock Spec inherit from. Eg: QSpec extends GebSpec.
It is the original method slightly modified with the original code commented out so you know what has been changed. I use this technique in several required places to alter Geb behaviour.
static {
Browser.metaClass.go = { Map params, String url ->
def newUrl = calculateUri(url, params)
// if (driver.currentUrl == newUrl) {
// driver.navigate().refresh()
// } else {
// driver.get(newUrl)
// }
driver.get(newUrl)
if (!page) {
page(Page)
}
}
}