iOS13使用后台处理器更新位置

iOS13使用后台处理器更新位置,ios,swift,swiftui,Ios,Swift,Swiftui,我知道我不是唯一有这个问题的人 基本上,SwiftUI似乎无法始终请求位置,即使它位于info.plist中,但您必须在以后添加一个调用(我已经这样做了) 我所看到的问题是,人们不会将其从应用程序使用期间更改为始终 那么,如何让后台处理器不断更新呢我看到苹果允许运行后台任务,仅此而已 我的信息列表 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//

我知道我不是唯一有这个问题的人

基本上,SwiftUI似乎无法始终请求位置,即使它位于info.plist中,但您必须在以后添加一个调用(我已经这样做了)

我所看到的问题是,人们不会将其从应用程序使用期间更改为始终

那么,如何让后台处理器不断更新呢我看到苹果允许运行后台任务,仅此而已

我的信息列表

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
    <key>CFBundleShortVersionString</key>
    <string>$(MARKETING_VERSION)</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>Delivering location based Fuel Price Updates, Weather, News &amp; Sports. As well as local offers.</string>
    <key>NSLocationUsageDescription</key>
    <string>Delivering location based Fuel Price Updates, Weather, News &amp; Sports. As well as local offers.</string>
    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <false/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                </dict>
            </array>
        </dict>
    </dict>
    <key>UIBackgroundModes</key>
    <array>
        <string>audio</string>
        <string>location</string>
    </array>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
    </array>
    <key>UIStatusBarHidden</key>
    <false/>
    <key>UIStatusBarStyle</key>
    <string>UIStatusBarStyleLightContent</string>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
</dict>
</plist>


在我看来,斯威夫特

 var lat: String{
        return "\(location.lastKnownLocation?.coordinate.latitude ?? 0.0)"
    }
    
    var lon: String{
        return "\(location.lastKnownLocation?.coordinate.longitude ?? 0.0)"
    }
    
    init() {
        self.location.startUpdating()
    }


我建议您做一些事情来改进您对位置的使用

首先,当您在iOS 13上请求“始终”位置权限时,用户实际上会得到“使用时”提示,这似乎让您感到困惑。在iOS 13.4上,您可以通过首先请求(并接收)“使用中”然后请求“始终”来触发“始终”提示。有些情况下,这是正确的方法,但我不认为你的应用程序是其中之一

你应该从2019年WWDC开始观看。它解释了临时位置权限是如何工作的

看看你的代码,你似乎在试图重新发明。核心位置可以为您做到这一点,仅当用户移动500米或以上时才提供更新;这听起来很适合您的用例

此外,根据您的用例,我看不出您实际上需要ios13+上的“始终”权限;在启用后台模式的情况下,您可以使用“使用时”进行重要的位置更改监控。当用户停止音频流时,您可以停止后台位置更新;当用户不播放音频时,您的应用程序没有充分的理由访问用户的位置

请注意,在iOS 12及更早版本中,您需要请求“始终”权限,但由于您提到了SwiftUI,因此iOS 13可能是您支持的最低版本


最后,关于Swift UI,应该在场景代理中创建一个对象,如
LocationServices
,并将其注入到环境中,而不是由视图创建。

您能澄清您的问题吗?你不会在任何地方总是请求许可。如果你想要总是,那么就要求总是,然而你的应用程序似乎并不真的需要总是。您也没有请求具有“使用时”权限的后台更新。我还建议你不要在视图初始化中初始化像位置管理器这样的对象,它应该由你的应用程序/场景代理创建并添加到环境中。你的应用程序看起来还可以使用显著的位置更改,并且能量更大efficient@Paulw11我们使用背景位置进行音频注入。我们已经建立了自己的音频喷射系统,用户在收听实况广播时可以获得最接近的燃油价格。另外,请查看//打印(lastknownLocation…,这是后面的一行。如果您对如何提高效率有任何建议,我很乐意看到。好的,但是如果您希望始终,请要求始终提前,用户将看到提示“使用时”如果他们同意,您将始终拥有临时权限。在您在后台使用位置一段时间后,用户返回到您的应用程序,他们将被提升以更新您的访问权限,但正如我所说的,您似乎并不总是需要。您应该查看“核心位置的新增功能”从WWDC 2019开始的课程,以了解临时授权是如何工作的。根据您的用例描述,您可以在背景中使用“使用时”的重大位置更改权限。这将每隔500米左右更新一次你的位置,这对你来说似乎很好。当用户启动和停止音频流时,你可以轻松启动和停止后台位置更新。当用户不从你的应用程序播放音频时,你不需要用户位置。所以,好吧,观看了视频,我认为你100%正确可以使用allowBackgroundLocationUpdate=true。但是我应该把它放在哪里?根据我对您的用例的理解,您应该在位置管理器上设置该属性,并在开始播放音频时启动LocatiInNuodate(或重要的位置更新),因为这是您需要位置的时候。
 var lat: String{
        return "\(location.lastKnownLocation?.coordinate.latitude ?? 0.0)"
    }
    
    var lon: String{
        return "\(location.lastKnownLocation?.coordinate.longitude ?? 0.0)"
    }
    
    init() {
        self.location.startUpdating()
    }