mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-13 20:03:46 +00:00
feat: Background download on iOS (#1442)
This commit is contained in:
1 parent
9d3221ebbb
commit
99924296ef
14 files changed
+383
-26
No files matched your search
@@ -21,6 +21,8 @@
|
||||
D0E623A929482D160001185E /* Libgopeed.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0E623A729482D030001185E /* Libgopeed.xcframework */; };
|
||||
D0E623AA29482D160001185E /* Libgopeed.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D0E623A729482D030001185E /* Libgopeed.xcframework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
DCA5B0FA95A8007ADEDACA1B /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70BC8D37FAC641C7F20125E8 /* Pods_Runner.framework */; };
|
||||
A10000000000000000000001 /* LocationKeepAliveManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000000000000000000002 /* LocationKeepAliveManager.swift */;};
|
||||
A10000000000000000000002 /* LocationKeepAliveManager.swift */ = {isa = PBXFileReference;lastKnownFileType = sourcecode.swift;path = LocationKeepAliveManager.swift;sourceTree = "<group>";};
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -153,18 +155,19 @@
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0C585CC72D41E36800FF2EC0 /* Runner.entitlements */,
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||
97C147021CF9000F007C117D /* Info.plist */,
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0C585CC72D41E36800FF2EC0 /* Runner.entitlements */,
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||
97C147021CF9000F007C117D /* Info.plist */,
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
|
||||
A10000000000000000000002 /* LocationKeepAliveManager.swift */,
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
|
||||
);
|
||||
path = Runner;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -376,12 +379,13 @@
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
|
||||
A10000000000000000000001 /* LocationKeepAliveManager.swift in Sources */,
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
@@ -32,6 +32,34 @@ import Libgopeed
|
||||
}
|
||||
})
|
||||
|
||||
let locationChannel = FlutterMethodChannel(
|
||||
name: "gopeed/location_keep_alive",
|
||||
binaryMessenger: controller.binaryMessenger
|
||||
)
|
||||
|
||||
locationChannel.setMethodCallHandler {
|
||||
(call: FlutterMethodCall, result: @escaping FlutterResult) in
|
||||
|
||||
switch call.method {
|
||||
|
||||
case "requestPermission":
|
||||
LocationKeepAliveManager.shared.requestPermission { authorized in
|
||||
result(authorized)
|
||||
}
|
||||
|
||||
case "start":
|
||||
LocationKeepAliveManager.shared.start()
|
||||
result(nil)
|
||||
|
||||
case "stop":
|
||||
LocationKeepAliveManager.shared.stop()
|
||||
result(nil)
|
||||
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
}
|
||||
}
|
||||
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
|
||||
SwiftFlutterForegroundTaskPlugin.setPluginRegistrantCallback(registerPlugins)
|
||||
|
||||
@@ -106,5 +106,15 @@
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>location</string>
|
||||
</array>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>Please go to Settings and change the location permission to "Always" so that the app can continue running in the background.</string>
|
||||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||
<string>Please go to Settings and change the location permission to "Always" so that the app can continue running in the background.</string>
|
||||
<key>NSLocationAlwaysUsageDescription</key>
|
||||
<string>Please go to Settings and change the location permission to "Always" so that the app can continue running in the background.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,126 @@
|
||||
import Foundation
|
||||
import CoreLocation
|
||||
|
||||
final class LocationKeepAliveManager: NSObject, CLLocationManagerDelegate {
|
||||
|
||||
static let shared = LocationKeepAliveManager()
|
||||
|
||||
private let locationManager = CLLocationManager()
|
||||
|
||||
private(set) var isRunning = false
|
||||
|
||||
private var permissionCompletion: ((Bool) -> Void)?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
locationManager.delegate = self
|
||||
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
|
||||
locationManager.distanceFilter = kCLDistanceFilterNone
|
||||
locationManager.pausesLocationUpdatesAutomatically = false
|
||||
|
||||
if #available(iOS 9.0, *) {
|
||||
locationManager.allowsBackgroundLocationUpdates = true
|
||||
}
|
||||
|
||||
if #available(iOS 14.0, *) {
|
||||
locationManager.showsBackgroundLocationIndicator = true
|
||||
}
|
||||
}
|
||||
|
||||
func requestPermission(completion: @escaping (Bool) -> Void) {
|
||||
let status = CLLocationManager.authorizationStatus()
|
||||
|
||||
switch status {
|
||||
case .authorizedAlways:
|
||||
completion(true)
|
||||
|
||||
case .authorizedWhenInUse:
|
||||
completion(false)
|
||||
|
||||
case .denied, .restricted:
|
||||
completion(false)
|
||||
|
||||
case .notDetermined:
|
||||
permissionCompletion = completion
|
||||
locationManager.requestAlwaysAuthorization()
|
||||
|
||||
@unknown default:
|
||||
completion(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func start() {
|
||||
guard !isRunning else {
|
||||
return
|
||||
}
|
||||
|
||||
let status = CLLocationManager.authorizationStatus()
|
||||
|
||||
guard status == .authorizedAlways else {
|
||||
return
|
||||
}
|
||||
|
||||
if #available(iOS 9.0, *) {
|
||||
locationManager.allowsBackgroundLocationUpdates = true
|
||||
}
|
||||
|
||||
locationManager.startUpdatingLocation()
|
||||
isRunning = true
|
||||
}
|
||||
|
||||
func stop() {
|
||||
locationManager.stopUpdatingLocation()
|
||||
isRunning = false
|
||||
}
|
||||
|
||||
private func handleAuthorizationStatus(
|
||||
_ status: CLAuthorizationStatus
|
||||
) {
|
||||
switch status {
|
||||
case .authorizedAlways:
|
||||
permissionCompletion?(true)
|
||||
permissionCompletion = nil
|
||||
|
||||
case .authorizedWhenInUse,
|
||||
.denied,
|
||||
.restricted:
|
||||
permissionCompletion?(false)
|
||||
permissionCompletion = nil
|
||||
|
||||
case .notDetermined:
|
||||
break
|
||||
|
||||
@unknown default:
|
||||
permissionCompletion?(false)
|
||||
permissionCompletion = nil
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
func locationManagerDidChangeAuthorization(
|
||||
_ manager: CLLocationManager
|
||||
) {
|
||||
handleAuthorizationStatus(manager.authorizationStatus)
|
||||
}
|
||||
|
||||
func locationManager(
|
||||
_ manager: CLLocationManager,
|
||||
didChangeAuthorization status: CLAuthorizationStatus
|
||||
) {
|
||||
handleAuthorizationStatus(status)
|
||||
}
|
||||
|
||||
func locationManager(
|
||||
_ manager: CLLocationManager,
|
||||
didUpdateLocations locations: [CLLocation]
|
||||
) {
|
||||
}
|
||||
|
||||
func locationManager(
|
||||
_ manager: CLLocationManager,
|
||||
didFailWithError error: Error
|
||||
) {
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user