Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/crash ios flutter engine rewrite #26

Merged
merged 21 commits into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6c97bc8
Updated the iOS cleanup methods to make sure we have a clean state af…
vanlooverenkoen Feb 17, 2021
3197d31
Updated the iOS codebase to support iOS 11 + & added extra logs
vanlooverenkoen Feb 17, 2021
d886286
Refactorred the background ios implementation
vanlooverenkoen Feb 18, 2021
4160015
Added extra logs
vanlooverenkoen Feb 18, 2021
d8b1525
Removed the static backgroundMethodChannel
vanlooverenkoen Feb 18, 2021
257a0d3
Rerun the flutterEngine.run method
vanlooverenkoen Feb 18, 2021
ba9c30d
Only executre the register plugins once
vanlooverenkoen Feb 18, 2021
97e40ea
Flutter engine force. unwrap
vanlooverenkoen Feb 18, 2021
4b72149
Only register the iOS plugins once
vanlooverenkoen Feb 18, 2021
3c9cd81
Has registered plugins
vanlooverenkoen Feb 18, 2021
fa8b2a7
Background channel rewrite
vanlooverenkoen Feb 18, 2021
e1927d8
Make sure the init background channel is triggered
vanlooverenkoen Feb 18, 2021
be7d293
pause location updates automaticly should be set to false
vanlooverenkoen Feb 18, 2021
45efd9e
Not initialized bug.
vanlooverenkoen Feb 18, 2021
3cc0316
Try to send to location update anyway
vanlooverenkoen Feb 18, 2021
c5cfcb6
Revert the initializedBackgroundCallbackStarted
vanlooverenkoen Feb 18, 2021
ff6cb5a
Updated the logger & cleanup the flutter engine if the run method cou…
vanlooverenkoen Feb 19, 2021
f9bfc24
Added an extra success log
vanlooverenkoen Feb 19, 2021
005c281
Move the log
vanlooverenkoen Feb 19, 2021
e213c4f
Removed options bracets
vanlooverenkoen Feb 19, 2021
e4d8c9f
Fixed if statements
vanlooverenkoen Feb 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ios/Classes/CustomLogger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
// Created by Dimmy Maenhout on 21/12/2020.
//

import os
import Foundation
struct CustomLogger {

static func log(message: String) {
if #available(iOS 10.0, *) {
let app = OSLog(subsystem: "com.icapps.background_location_tracker", category: "background tracker")
os_log("🔥 background-location log: %{public}@", log: app, type: .error, message)
}
if SharedPrefsUtil.isLoggingEnabled() {
print(message)
}
Expand Down
4 changes: 4 additions & 0 deletions ios/Classes/LocationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class LocationManager {
let manager = CLLocationManager()
manager.activityType = .automotiveNavigation
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.pausesLocationUpdatesAutomatically = false
if #available(iOS 11, *) {
manager.showsBackgroundLocationIndicator = true
}
if #available(iOS 9.0, *) {
manager.allowsBackgroundLocationUpdates = true
}
Expand Down
109 changes: 77 additions & 32 deletions ios/Classes/SwiftBackgroundLocationTrackerPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ public class SwiftBackgroundLocationTrackerPlugin: FlutterPluginAppLifeCycleDele

static let identifier = "com.icapps.background_location_tracker"

private let flutterThreadLabelPrefix = "\(identifier).BackgroundLocationTracker"
private static let flutterThreadLabelPrefix = "\(identifier).BackgroundLocationTracker"

private static var foregroundChannel: ForegroundChannel? = nil
private static var backgroundMethodChannel: FlutterMethodChannel? = nil

private static var flutterEngine: FlutterEngine? = nil
private static var hasRegisteredPlugins = false
private static var initializedBackgroundCallbacks = false
private static var initializedBackgroundCallbacksStarted = false
private static var locationData: [String: Any]? = nil

private static var flutterPluginRegistrantCallback: FlutterPluginRegistrantCallback?

Expand All @@ -35,6 +42,55 @@ extension SwiftBackgroundLocationTrackerPlugin: FlutterPlugin {
locationManager.delegate = self
SwiftBackgroundLocationTrackerPlugin.foregroundChannel?.handle(call, result: result)
}

public static func getFlutterEngine()-> FlutterEngine? {
if (flutterEngine == nil) {
let flutterEngine = FlutterEngine(name: flutterThreadLabelPrefix, project: nil, allowHeadlessExecution: true)

guard let callbackHandle = SharedPrefsUtil.getCallbackHandle(),
let flutterCallbackInformation = FlutterCallbackCache.lookupCallbackInformation(callbackHandle) else {
CustomLogger.log(message: "No flutter callback cache ...")
return nil
}
flutterEngine.run(withEntrypoint: flutterCallbackInformation.callbackName, libraryURI: flutterCallbackInformation.callbackLibraryPath)
SwiftBackgroundLocationTrackerPlugin.flutterPluginRegistrantCallback?(flutterEngine)
self.flutterEngine = flutterEngine
}
return flutterEngine
}

public static func initBackgroundMethodChannel(flutterEngine: FlutterEngine) {
if (backgroundMethodChannel == nil) {
let backgroundMethodChannel = FlutterMethodChannel(name: SwiftBackgroundLocationTrackerPlugin.BACKGROUND_CHANNEL_NAME, binaryMessenger: flutterEngine.binaryMessenger)
backgroundMethodChannel.setMethodCallHandler { (call, result) in
switch call.method {
case BackgroundMethods.initialized.rawValue:
initializedBackgroundCallbacks = true
if let data = SwiftBackgroundLocationTrackerPlugin.locationData {
CustomLogger.log(message: "Initialized with cached value, sending location update")
sendLocationupdate(locationData: data)
} else {
CustomLogger.log(message: "Initialized without cached value")
}
result(true)
default:
CustomLogger.log(message: "Not implemented method -> \(call.method)")
result(FlutterMethodNotImplemented)
}
}
self.backgroundMethodChannel = backgroundMethodChannel
}
}

public static func sendLocationupdate(locationData: [String: Any]){
guard let backgroundMethodChannel = SwiftBackgroundLocationTrackerPlugin.backgroundMethodChannel else {
CustomLogger.log(message: "No background channel available ...")
return
}
backgroundMethodChannel.invokeMethod(BackgroundMethods.onLocationUpdate.rawValue, arguments: locationData, result: { flutterResult in
CustomLogger.log(message: "Received result: \(flutterResult.debugDescription)")
})
}
}

fileprivate enum BackgroundMethods: String {
Expand All @@ -53,38 +109,27 @@ extension SwiftBackgroundLocationTrackerPlugin: CLLocationManagerDelegate {

CustomLogger.log(message: "NEW LOCATION: \(location.coordinate.latitude): \(location.coordinate.longitude)")

guard let callbackHandle = SharedPrefsUtil.getCallbackHandle(),
let flutterCallbackInformation = FlutterCallbackCache.lookupCallbackInformation(callbackHandle)
else { return }

var flutterEngine: FlutterEngine? = FlutterEngine(name: flutterThreadLabelPrefix, project: nil, allowHeadlessExecution: true)
flutterEngine!.run(withEntrypoint: flutterCallbackInformation.callbackName, libraryURI: flutterCallbackInformation.callbackLibraryPath)
SwiftBackgroundLocationTrackerPlugin.flutterPluginRegistrantCallback?(flutterEngine!)

var backgroundMethodChannel: FlutterMethodChannel? = FlutterMethodChannel(name: SwiftBackgroundLocationTrackerPlugin.BACKGROUND_CHANNEL_NAME, binaryMessenger: flutterEngine!.binaryMessenger)


func cleanupFlutterResources() {
flutterEngine?.destroyContext()
backgroundMethodChannel = nil
flutterEngine = nil
}
let locationData: [String: Any] = [
"lat": location.coordinate.latitude,
"lon": location.coordinate.longitude,
"logging_enabled": SharedPrefsUtil.isLoggingEnabled(),
]

backgroundMethodChannel?.setMethodCallHandler { (call, result) in
switch call.method {
case BackgroundMethods.initialized.rawValue:
result(true)
let locationData :[String: Any] = [
"lat": location.coordinate.latitude,
"lon": location.coordinate.longitude,
"logging_enabled": SharedPrefsUtil.isLoggingEnabled(),
]
backgroundMethodChannel?.invokeMethod(BackgroundMethods.onLocationUpdate.rawValue, arguments: locationData, result: { flutterResult in
cleanupFlutterResources()
})
default:
cleanupFlutterResources()
result(FlutterMethodNotImplemented)
if (SwiftBackgroundLocationTrackerPlugin.initializedBackgroundCallbacks) {
CustomLogger.log(message: "INITIALIZED, ready to send location updates")
SwiftBackgroundLocationTrackerPlugin.sendLocationupdate(locationData: locationData)
} else {
CustomLogger.log(message: "NOT YET INITIALIZED. Cache the location data")
SwiftBackgroundLocationTrackerPlugin.locationData = locationData

if (!SwiftBackgroundLocationTrackerPlugin.initializedBackgroundCallbacksStarted){
SwiftBackgroundLocationTrackerPlugin.initializedBackgroundCallbacksStarted = true

guard let flutterEngine = SwiftBackgroundLocationTrackerPlugin.getFlutterEngine() else {
CustomLogger.log(message: "No Flutter engine available ...")
return
}
SwiftBackgroundLocationTrackerPlugin.initBackgroundMethodChannel(flutterEngine: flutterEngine)
}
}
}
Expand Down