-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[Connectivity] add a method to request location on iOS (for iOS 13) #1999
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Long term I'm hoping this will move to a shared plugin, so I'm fine with whatever you want to do here.
However, it feels like we're conflating requesting permission and checking what the current status is. I'm wondering if there should be separate APIs for each. What do you think?
Compare with the React Native implementation
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key> | ||
<string>Location service</string> | ||
<key>NSLocationWhenInUseUsageDescription</key> | ||
<string>locaiton service in use</string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo, also I think you should put an English sentence here
@@ -22,6 +22,10 @@ | |||
<string>1</string> | |||
<key>LSRequiresIPhoneOS</key> | |||
<true/> | |||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key> | |||
<string>Location service</string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should put an appropriate English sentence here since it's an example app.
packages/connectivity/README.md
Outdated
|
||
You can follow issue [#37804](https://github.com/flutter/flutter/issues/37804) for the changes required to return valid SSID and BSSID values with iOS 13. | ||
* `NSLocationAlwaysAndWhenInUseUsageDescription` - describe why the app needs access to the user’s location information all the time (foreground and background). _Privacy - Location Always and When In Use Usage Description_ in the visual editor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* `NSLocationAlwaysAndWhenInUseUsageDescription` - describe why the app needs access to the user’s location information all the time (foreground and background). _Privacy - Location Always and When In Use Usage Description_ in the visual editor. | |
* `NSLocationAlwaysAndWhenInUseUsageDescription` - describe why the app needs access to the user’s location information all the time (foreground and background). This is called _Privacy - Location Always Usage Description_ in the visual editor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be wrong here but I think it should just be Privacy - Location Always Usage Description
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I thought before writing this PR too :) Appearently the name has been changed.
https://developer.apple.com/documentation/bundleresources/information_property_list/nslocationalwaysandwheninuseusagedescription?language=objc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add "This is called" from my suggestion above?
CLAuthorizationStatus status = CLLocationManager.authorizationStatus; | ||
switch (status) { | ||
case kCLAuthorizationStatusNotDetermined: { | ||
self.result = result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's a race condition here where two calls to requestLocationServiceAuthorizationIfUndetermined
in quick succession could lead to result
being clobbered before being invoked. Consider returning an error if self.result != null
or handling the case gracefully.
} | ||
|
||
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { | ||
[self requestLocationServiceAuthorizationIfUndetermined:self.result always:nil]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably set self.result
to nil
here so we don't accidentally notify it more than once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a new class FLTConnectivityLocationHandler
to handle all the location related stuff so now the result is inline.
FLTConnectivityLocationHandler handles the race condition that you mentioned by returning notDetermined if a request is in process.
Sure. My initial implementation did actually have these separated. I can add it back. |
Co-Authored-By: Collin Jackson <jackson@google.com>
Co-Authored-By: Collin Jackson <jackson@google.com>
Co-Authored-By: Collin Jackson <jackson@google.com>
Co-Authored-By: Collin Jackson <jackson@google.com>
Co-Authored-By: Collin Jackson <jackson@google.com>
Co-Authored-By: Collin Jackson <jackson@google.com>
Co-Authored-By: Collin Jackson <jackson@google.com>
Co-Authored-By: Collin Jackson <jackson@google.com>
Co-Authored-By: Collin Jackson <jackson@google.com>
@collinjackson It is ready for another review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with some minor nits.
Might want to integration test the default value of getLocationServiceAuthorization
even if the infrastructure's not quite there yet to do requestLocationServiceAuthorization
yet.
packages/connectivity/README.md
Outdated
|
||
You can follow issue [#37804](https://github.com/flutter/flutter/issues/37804) for the changes required to return valid SSID and BSSID values with iOS 13. | ||
* `NSLocationAlwaysAndWhenInUseUsageDescription` - describe why the app needs access to the user’s location information all the time (foreground and background). _Privacy - Location Always and When In Use Usage Description_ in the visual editor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add "This is called" from my suggestion above?
@@ -22,6 +22,10 @@ | |||
<string>1</string> | |||
<key>LSRequiresIPhoneOS</key> | |||
<true/> | |||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key> | |||
<string>This app requires accessing your location information all the time to get WIFI information.</string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check caps on WIFI, consider wi-fi
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key> | ||
<string>This app requires accessing your location information all the time to get WIFI information.</string> | ||
<key>NSLocationWhenInUseUsageDescription</key> | ||
<string>This app requires accessing your location information when the app is in foreground to get WIFI information.</string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check caps on WIFI, consider wi-fi
status == LocationAuthorizationStatus.authorizedWhenInUse) { | ||
wifiName = await _connectivity.getWifiName(); | ||
} else { | ||
print( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not thrilled about this print statement, it seems like it could clutter the logs. Do you think it's necessary?
} | ||
|
||
if (self.completion) { | ||
// If a request is still in process, immdediately return. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// If a request is still in process, immdediately return. | |
// If a request is still in process, immediately return. |
/// | ||
/// Returns a [LocationAuthorizationStatus] after user authorized or denied the location on this request. | ||
/// | ||
/// if the location information needs to be accessible all the time, set `requestAlwaysLocationUsage` to true. If user has |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// if the location information needs to be accessible all the time, set `requestAlwaysLocationUsage` to true. If user has | |
/// If the location information needs to be accessible all the time, set `requestAlwaysLocationUsage` to `true`. If user has |
/// | ||
/// See also [requestLocationServiceAuthorization] for requesting a location service authorization. | ||
Future<LocationAuthorizationStatus> getLocationServiceAuthorization() async { | ||
//Just `assert(Platform.isIOS)` will disable us to do dart side unit testing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//Just `assert(Platform.isIOS)` will disable us to do dart side unit testing. | |
// Just `assert(Platform.isIOS)` will prevent us from doing Dart side unit testing. |
@@ -93,6 +94,125 @@ class Connectivity { | |||
Future<String> getWifiIP() async { | |||
return await methodChannel.invokeMethod<String>('wifiIPAddress'); | |||
} | |||
|
|||
/// Request to authorize the location service. Only on iOS. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Request to authorize the location service. Only on iOS. | |
/// Request to authorize the location service (only on iOS). |
I think Dartdoc comments are supposed to have tight first sentence with no other sentences on the first line. https://dart.dev/guides/language/effective-dart/documentation
return _convertLocationStatusString(result); | ||
} | ||
|
||
/// Get the current location service authorization. Only on iOS. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Get the current location service authorization. Only on iOS. | |
/// Get the current location service authorization (only on iOS). |
@collinjackson Thanks for the review. I updated the code with your review suggests; also added a driver test to test the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you have some test failures but I'm LGTM on this once you've resolved them.
Description
Starting from iOS 13. Certain apps need to have user authorized location service to get WIFI information using
CNCopyCurrentNetworkInfo
. Detailed in flutter/flutter#37804We add a helper method for the plugin users to request or get location service authorization.
Also updated the REAMDE to explain the iOS 13 changes.
Related Issues
flutter/flutter#37804
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]
). This will ensure a smooth and quick review process.///
).flutter analyze
) does not report any problems on my PR.Breaking Change
Does your PR require plugin users to manually update their apps to accommodate your change?