Run autoformat

This commit is contained in:
Milan Stute
2021-03-15 12:56:01 +01:00
parent 2f32efef24
commit 1b6eadb301
5 changed files with 98 additions and 102 deletions

View File

@@ -9,15 +9,15 @@
import Combine
import Foundation
import SwiftUI
import OSLog
import SwiftUI
class AccessoryController: ObservableObject {
@Published var accessories: [Accessory]
var selfObserver: AnyCancellable?
var listElementsObserver = [AnyCancellable]()
let findMyController: FindMyController
init(accessories: [Accessory], findMyController: FindMyController) {
self.accessories = accessories
self.findMyController = findMyController
@@ -91,7 +91,7 @@ class AccessoryController: ObservableObject {
}
return accessory
}
/// Export the accessories property list so it can be imported at another location
func export(accessories: [Accessory]) throws -> URL {
let propertyList = try PropertyListEncoder().encode(accessories)
@@ -109,7 +109,8 @@ class AccessoryController: ObservableObject {
let result = savePanel.runModal()
if result == .OK,
let url = savePanel.url {
let url = savePanel.url
{
// Store the accessory file
try propertyList.write(to: url)
@@ -130,47 +131,46 @@ class AccessoryController: ObservableObject {
let result = openPanel.runModal()
if result == .OK,
let url = openPanel.url {
let url = openPanel.url
{
let propertyList = try Data(contentsOf: url)
var importedAccessories = try PropertyListDecoder().decode([Accessory].self, from: propertyList)
var updatedAccessories = self.accessories
// Filter out accessories with the same id (no duplicates)
importedAccessories = importedAccessories.filter({acc in !self.accessories.contains(where: {acc.id == $0.id})})
importedAccessories = importedAccessories.filter({ acc in !self.accessories.contains(where: { acc.id == $0.id }) })
updatedAccessories.append(contentsOf: importedAccessories)
updatedAccessories.sort(by: {$0.name < $1.name})
updatedAccessories.sort(by: { $0.name < $1.name })
self.accessories = updatedAccessories
//Update reports automatically. Do not report errors from here
self.downloadLocationReports { result in}
self.downloadLocationReports { result in }
}
}
enum ImportError: Error {
case cancelled
}
//MARK: Location reports
/// Download the location reports from
/// - Parameter completion: called when the reports have been succesfully downloaded or the request has failed
func downloadLocationReports(completion: @escaping (Result<Void,OpenHaystackMainView.AlertType>) -> Void) {
/// Download the location reports from
/// - Parameter completion: called when the reports have been succesfully downloaded or the request has failed
func downloadLocationReports(completion: @escaping (Result<Void, OpenHaystackMainView.AlertType>) -> Void) {
AnisetteDataManager.shared.requestAnisetteData { result in
switch result {
case .failure(_):
completion(.failure(.activatePlugin))
case .success(let accountData):
guard let token = accountData.searchPartyToken,
token.isEmpty == false else {
token.isEmpty == false
else {
completion(.failure(.searchPartyToken))
return
}
self.findMyController.fetchReports(for: self.accessories, with: token) { result in
switch result {
case .failure(let error):
@@ -180,17 +180,17 @@ class AccessoryController: ObservableObject {
let reports = devices.compactMap({ $0.reports }).flatMap({ $0 })
if reports.isEmpty {
completion(.failure(.noReportsFound))
}else {
} else {
self.updateWithDecryptedReports(devices: devices)
completion(.success(()))
}
}
}
}
}
}
}
class AccessoryControllerPreview: AccessoryController {

View File

@@ -1,4 +1,4 @@
//
//
// OpenHaystack Tracking personal Bluetooth devices via Apple's Find My network
//
// Copyright © 2021 Secure Mobile Networking Lab (SEEMOO)
@@ -21,7 +21,7 @@ struct ManageAccessoriesView: View {
@Binding var focusedAccessory: Accessory?
@Binding var accessoryToDeploy: Accessory?
@Binding var showESP32DeploySheet: Bool
@State var showMailPopup = false
var body: some View {
@@ -74,23 +74,28 @@ struct ManageAccessoriesView: View {
.listStyle(SidebarListStyle())
}
/// All toolbar buttons shown
/// All toolbar buttons shown
var toolbarView: some View {
Group {
Spacer()
Button(action: self.importAccessories, label: {
Label("Import accessories", systemImage: "square.and.arrow.down")
})
Button(
action: self.importAccessories,
label: {
Label("Import accessories", systemImage: "square.and.arrow.down")
}
)
.help("Import accessories from a file")
Button(action: self.exportAccessories, label: {
Label("Export accessories", systemImage: "square.and.arrow.up")
})
Button(
action: self.exportAccessories,
label: {
Label("Export accessories", systemImage: "square.and.arrow.up")
}
)
.help("Export all accessories to a file")
Button(action: self.addAccessory) {
Label("Add accessory", systemImage: "plus")
}
@@ -120,25 +125,26 @@ struct ManageAccessoriesView: View {
self.alertType = .keyError
}
}
func exportAccessories() {
do {
_ = try self.accessoryController.export(accessories: self.accessories)
}catch {
} catch {
self.alertType = .exportFailed
}
}
func importAccessories() {
do {
try self.accessoryController.importAccessories()
}catch {
} catch {
if let importError = error as? AccessoryController.ImportError,
importError == .cancelled {
importError == .cancelled
{
//User cancelled the import. No error
return
}
self.alertType = .importFailed
}
}

View File

@@ -15,7 +15,7 @@ struct OpenHaystackMainView: View {
@State var loading = false
@EnvironmentObject var accessoryController: AccessoryController
var accessories: [Accessory] {
return self.accessoryController.accessories
}
@@ -30,9 +30,9 @@ struct OpenHaystackMainView: View {
@State var focusedAccessory: Accessory?
@State var accessoryToDeploy: Accessory?
@State var showMailPlugInPopover = false
@State var mailPluginIsActive = false
@State var showESP32DeploySheet = false
var body: some View {
@@ -104,39 +104,43 @@ struct OpenHaystackMainView: View {
}
}
}
/// All toolbar items shown
var toolbarView: some View {
Group {
Picker("", selection: self.$mapType) {
Text("Satellite").tag(MKMapType.hybrid)
Text("Standard").tag(MKMapType.standard)
}
.pickerStyle(SegmentedPickerStyle())
Button(action: {
if !self.mailPluginIsActive {
self.showMailPlugInPopover.toggle()
}else {
self.downloadLocationReports()
Button(
action: {
if !self.mailPluginIsActive {
self.showMailPlugInPopover.toggle()
} else {
self.downloadLocationReports()
}
},
label: {
HStack {
Circle()
.fill(self.mailPluginIsActive ? Color.green : Color.orange)
.frame(width: 8, height: 8)
Label("Reload", systemImage: "arrow.clockwise")
.disabled(!self.mailPluginIsActive)
}
}
},label: {
HStack {
Circle()
.fill(self.mailPluginIsActive ? Color.green : Color.orange)
.frame(width: 8, height: 8)
Label("Reload", systemImage: "arrow.clockwise")
.disabled(!self.mailPluginIsActive)
}
})
)
.disabled(self.accessories.isEmpty)
.popover(isPresented: $showMailPlugInPopover, content: {
self.mailStatePopover
})
.popover(
isPresented: $showMailPlugInPopover,
content: {
self.mailStatePopover
})
}
}
@@ -171,7 +175,7 @@ struct OpenHaystackMainView: View {
case .failure(let alert):
if alert == .noReportsFound {
self.popUpAlertType = .noReportsFound
}else {
} else {
self.alertType = alert
}
case .success(_):
@@ -179,15 +183,15 @@ struct OpenHaystackMainView: View {
}
}
}
var mailStatePopover: some View {
HStack {
Image(systemName: "envelope")
.foregroundColor(self.mailPluginIsActive ? .green : .red)
if self.mailPluginIsActive {
Text("The mail plug-in is up and running")
}else {
} else {
Text("Cannot connect to the mail plug-in. Open Apple Mail and make sure the plug-in is enabled")
.lineLimit(10)
.multilineTextAlignment(.leading)
@@ -234,7 +238,7 @@ struct OpenHaystackMainView: View {
}
}
func checkPluginIsRunning(silent: Bool=false, _ completion: ((Bool) -> Void)?) {
func checkPluginIsRunning(silent: Bool = false, _ completion: ((Bool) -> Void)?) {
// Check if Mail plugin is active
AnisetteDataManager.shared.requestAnisetteData { (result) in
DispatchQueue.main.async {
@@ -242,7 +246,7 @@ struct OpenHaystackMainView: View {
case .success(let accountData):
withAnimation {
if let token = accountData.searchPartyToken {
if let token = accountData.searchPartyToken {
self.searchPartyToken = String(data: token, encoding: .ascii) ?? ""
if self.searchPartyToken.isEmpty == false {
self.searchPartyTokenLoaded = true
@@ -263,11 +267,13 @@ struct OpenHaystackMainView: View {
}
self.mailPluginIsActive = false
completion?(false)
//Check again in 5s
DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
self.checkPluginIsRunning(silent: true, nil)
})
DispatchQueue.main.asyncAfter(
deadline: .now() + 5,
execute: {
self.checkPluginIsRunning(silent: true, nil)
})
}
}
}
@@ -362,9 +368,10 @@ struct OpenHaystackMainView: View {
primaryButton: microbitButton,
secondaryButton: esp32Button)
case .downloadingReportsFailed:
return Alert(title: Text("Downloading locations failed"),
message: Text("We could not download any locations from Apple. Please try again later"),
dismissButton: Alert.Button.okay())
return Alert(
title: Text("Downloading locations failed"),
message: Text("We could not download any locations from Apple. Please try again later"),
dismissButton: Alert.Button.okay())
case .exportFailed:
return Alert(
title: Text("Export failed"),

View File

@@ -31,22 +31,5 @@ struct OpenHaystackApp: App {
.commands {
SidebarCommands()
}
}
}
//MARK: Environment objects
private struct FindMyControllerEnvironmentKey: EnvironmentKey {
static let defaultValue: FindMyController = FindMyController()
}
private struct AccessoryControllerEnvironmentKey: EnvironmentKey {
static let defaultValue: AccessoryController = {
if ProcessInfo().arguments.contains("-preview") {
return AccessoryControllerPreview(accessories: PreviewData.accessories, findMyController: FindMyController())
} else {
return AccessoryController()
}
}()
}

View File

@@ -33,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, copy) NSLocale *locale;
@property(nonatomic, copy) NSTimeZone *timeZone;
@property(nonatomic, copy) NSData * _Nullable searchPartyToken;
@property(nonatomic, copy) NSData *_Nullable searchPartyToken;
- (instancetype)initWithMachineID:(NSString *)machineID
oneTimePassword:(NSString *)oneTimePassword