iOS 接入flutter插件 permission_handler,定位權(quán)限始終獲取不正確

因?yàn)轫?xiàng)目需要,使用原生swift + flutter 的混編,因?yàn)轫?xiàng)目涉及定位、導(dǎo)航功能,所以權(quán)限這部分不可能繞過(guò),flutter 權(quán)限的插件以及版本號(hào)如下所示

permission_handler: ^11.4.0

各種配置(info.plis 文件、網(wǎng)絡(luò)、flutter環(huán)境)這些都是確定沒(méi)有任何問(wèn)題的,但是位置獲取權(quán)限始終都是

PermissionStatus.permanentlyDenied

因?yàn)榻佑|flutter沒(méi)多久,Android的小伙伴又是一點(diǎn)不懂iOS,一般認(rèn)為Android上面沒(méi)有問(wèn)題,那么iOS上就肯定沒(méi)有問(wèn)題(說(shuō)多了都是淚),一般這種混合開(kāi)發(fā)的項(xiàng)目Android的話(huà)語(yǔ)權(quán)是比較重的,更多是傾向于敏捷,性能方面會(huì)稍微放松,一切為了先實(shí)現(xiàn)功能,從純?cè)暤慕嵌瘸霭l(fā),不論是Object-C 還是Swift,位置權(quán)限至少包含以下

永不
下次詢(xún)問(wèn)或共享時(shí)
使用App期間
始終

一直覺(jué)得是哪里配置錯(cuò)了,因?yàn)锳ndroid確實(shí)是可以的,可實(shí)在是找不到具體問(wèn)題所在,只能采用最原始的方式,查一下flutter 的這個(gè) permission_handler 插件
https://pub.dev/packages/permission_handler
依據(jù)經(jīng)驗(yàn),主要關(guān)注的肯定就是平臺(tái)的差異化配置,結(jié)果發(fā)現(xiàn)如下信息

image.png

我們主要關(guān)注iOS的配置,結(jié)果發(fā)現(xiàn)少了最關(guān)鍵的第一步
Add the following to your Podfile file:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)

    target.build_configurations.each do |config|
      # You can remove unused permissions here
      # for more information: https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler_apple/ios/Classes/PermissionHandlerEnums.h
      # e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.calendar
        'PERMISSION_EVENTS=1',
        
        ## dart: PermissionGroup.calendarFullAccess
        'PERMISSION_EVENTS_FULL_ACCESS=1',

        ## dart: PermissionGroup.reminders
        'PERMISSION_REMINDERS=1',

        ## dart: PermissionGroup.contacts
        'PERMISSION_CONTACTS=1',

        ## dart: PermissionGroup.camera
        'PERMISSION_CAMERA=1',

        ## dart: PermissionGroup.microphone
        'PERMISSION_MICROPHONE=1',

        ## dart: PermissionGroup.speech
        'PERMISSION_SPEECH_RECOGNIZER=1',

        ## dart: PermissionGroup.photos
        'PERMISSION_PHOTOS=1',

        ## The 'PERMISSION_LOCATION' macro enables the `locationWhenInUse` and `locationAlways` permission. If
        ## the application only requires `locationWhenInUse`, only specify the `PERMISSION_LOCATION_WHENINUSE`
        ## macro.
        ##
        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        'PERMISSION_LOCATION=1',
        'PERMISSION_LOCATION_WHENINUSE=0',

        ## dart: PermissionGroup.notification
        'PERMISSION_NOTIFICATIONS=1',

        ## dart: PermissionGroup.mediaLibrary
        'PERMISSION_MEDIA_LIBRARY=1',

        ## dart: PermissionGroup.sensors
        'PERMISSION_SENSORS=1',

        ## dart: PermissionGroup.bluetooth
        'PERMISSION_BLUETOOTH=1',

        ## dart: PermissionGroup.appTrackingTransparency
        'PERMISSION_APP_TRACKING_TRANSPARENCY=1',

        ## dart: PermissionGroup.criticalAlerts
        'PERMISSION_CRITICAL_ALERTS=1',

        ## dart: PermissionGroup.criticalAlerts
        'PERMISSION_ASSISTANT=1',
      ]

    end
  end
end

這個(gè)庫(kù)權(quán)限相對(duì)來(lái)說(shuō)比較全面,我們需要的是位置相關(guān),主要查看如下所示部分

## The 'PERMISSION_LOCATION' macro enables the `locationWhenInUse` and `locationAlways` permission. If
        ## the application only requires `locationWhenInUse`, only specify the `PERMISSION_LOCATION_WHENINUSE`
        ## macro.
        ##
        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        'PERMISSION_LOCATION=1',
        'PERMISSION_LOCATION_WHENINUSE=0',

簡(jiǎn)單粗暴的理解為這樣

  • PERMISSION_LOCATION 包含 (locationWhenInUse、locationAlways)
  • PERMISSION_LOCATION_WHENINUSE 僅僅包含(locationWhenInUse)
    這里建議使用 PERMISSION_LOCATION ,便于后期適應(yīng)復(fù)雜業(yè)務(wù)場(chǎng)景,這里面還有其他的一些權(quán)限,感興趣可以研究研究,也沒(méi)有什么難度
    經(jīng)過(guò)上述的配置,iOS 位置權(quán)限這部分也沒(méi)啥問(wèn)題了,至此,大功告成
    這里貼出一些可供參考的flutter代碼片段,僅供小伙伴參考
  Future<void> _requestLocationPermission() async {
    // 檢查當(dāng)前權(quán)限狀態(tài)
    var status = await Permission.location.status;
    if (status == PermissionStatus.denied) {
      // 首次申請(qǐng)"使用應(yīng)用期間"權(quán)限
      status = await Permission.locationWhenInUse.request();
      if (status == PermissionStatus.granted) {
        // 成功獲取"使用應(yīng)用期間"權(quán)限
        print("已獲取使用應(yīng)用期間的定位權(quán)限");

        // 檢查是否需要始終權(quán)限
        bool needAlwaysPermission = true; // 根據(jù)業(yè)務(wù)需求決定
        if (needAlwaysPermission) {
          await _requestAlwaysPermission();
        }
      } else if (status == PermissionStatus.permanentlyDenied) {
        // 永久拒絕,引導(dǎo)至設(shè)置
        print("用戶(hù)拒絕了使用應(yīng)用期間的定位權(quán)限");
        openAppSettings();
      }
    } else if (status == PermissionStatus.granted) {
      // 已有權(quán)限,檢查是否為"始終允許"
      if (await Permission.locationAlways.isGranted) {
        print("已獲取始終允許的定位權(quán)限");
      } else {
        // 只有"使用期間"權(quán)限,可選擇是否請(qǐng)求"始終允許"
        await _requestAlwaysPermission();
      }
    } else if (status == PermissionStatus.permanentlyDenied) {
      // 永久拒絕,引導(dǎo)至設(shè)置
      openAppSettings();
    }
  }

  Future<void> _requestAlwaysPermission() async {
    // 請(qǐng)求"始終允許"權(quán)限
    var status = await Permission.locationAlways.request();
    if (status == PermissionStatus.granted) {
      print("成功獲取始終允許的定位權(quán)限");
    } else {
      print("用戶(hù)拒絕了始終允許的定位權(quán)限");
    }
  }

上面的 openAppSettings() 是跳轉(zhuǎn)至iOS系統(tǒng)權(quán)限設(shè)置的,具體的業(yè)務(wù)可以根據(jù)上面不同權(quán)限類(lèi)型去自行設(shè)置,比如:

  • 用戶(hù)拒絕權(quán)限后可能需要給出一定的提示(一般就是個(gè)彈出框),引導(dǎo)用戶(hù)去開(kāi)啟權(quán)限
  • 用戶(hù)授權(quán)后可能會(huì)定位或者導(dǎo)航等等。。。

總結(jié):

  • 不要迷信他人的決定,根據(jù)自身的經(jīng)驗(yàn),大膽驗(yàn)證自己的猜想
    • 跨行被指導(dǎo)一定要慎重,一定不要屈服,不然很容易背鍋(我經(jīng)常聽(tīng)到的一句話(huà):你看看Android都沒(méi)事,就你iOS有問(wèn)題,基本都是因?yàn)閒lutter 的平臺(tái)差異化配置導(dǎo)致)
  • 必要的時(shí)候一定要細(xì)看文檔,特別是混合開(kāi)發(fā)中的一些差異化配置,沒(méi)有人有義務(wù)一定兼容iOS,因?yàn)樗麄円泊_實(shí)不懂
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容