SwiftUI: show iss position on map
This commit is contained in:
parent
9b9137dfc5
commit
132969d847
4 changed files with 81 additions and 20 deletions
|
@ -18,6 +18,7 @@
|
|||
1ABFB8C723AFF5CE003D807E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1ABFB8C623AFF5CE003D807E /* Preview Assets.xcassets */; };
|
||||
1ABFB8CA23AFF5CE003D807E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1ABFB8C823AFF5CE003D807E /* LaunchScreen.storyboard */; };
|
||||
1AC2439025A1D57700F17D2F /* IssPositionPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AC2438F25A1D57700F17D2F /* IssPositionPublisher.swift */; };
|
||||
1AD2EC6A25E9984900CCEE81 /* ISSMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AD2EC6925E9984900CCEE81 /* ISSMapView.swift */; };
|
||||
1E1255057DE614781855FC02 /* libPods-PeopleInSpaceSwiftUI.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 28681F6577A67864E2C2D9B4 /* libPods-PeopleInSpaceSwiftUI.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
@ -35,6 +36,7 @@
|
|||
1ABFB8C923AFF5CE003D807E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
1ABFB8CB23AFF5CE003D807E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
1AC2438F25A1D57700F17D2F /* IssPositionPublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IssPositionPublisher.swift; sourceTree = "<group>"; };
|
||||
1AD2EC6925E9984900CCEE81 /* ISSMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ISSMapView.swift; sourceTree = "<group>"; };
|
||||
28681F6577A67864E2C2D9B4 /* libPods-PeopleInSpaceSwiftUI.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PeopleInSpaceSwiftUI.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
56CD7101BBBC60F561BFB049 /* Pods-PeopleInSpaceSwiftUI.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PeopleInSpaceSwiftUI.release.xcconfig"; path = "Target Support Files/Pods-PeopleInSpaceSwiftUI/Pods-PeopleInSpaceSwiftUI.release.xcconfig"; sourceTree = "<group>"; };
|
||||
E9A29AFE5FFFB564C509840A /* Pods-PeopleInSpaceSwiftUI.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PeopleInSpaceSwiftUI.debug.xcconfig"; path = "Target Support Files/Pods-PeopleInSpaceSwiftUI/Pods-PeopleInSpaceSwiftUI.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
|
@ -102,6 +104,7 @@
|
|||
1ABD44F923B00008008387E3 /* ViewModel.swift */,
|
||||
1AA82EEC25052E1E00193051 /* ImageView.swift */,
|
||||
1AC2438F25A1D57700F17D2F /* IssPositionPublisher.swift */,
|
||||
1AD2EC6925E9984900CCEE81 /* ISSMapView.swift */,
|
||||
);
|
||||
path = PeopleInSpaceSwiftUI;
|
||||
sourceTree = "<group>";
|
||||
|
@ -225,6 +228,7 @@
|
|||
1AC2439025A1D57700F17D2F /* IssPositionPublisher.swift in Sources */,
|
||||
1ABFB8BE23AFF5CC003D807E /* AppDelegate.swift in Sources */,
|
||||
1ABFB8C023AFF5CC003D807E /* SceneDelegate.swift in Sources */,
|
||||
1AD2EC6A25E9984900CCEE81 /* ISSMapView.swift in Sources */,
|
||||
1ABD44FA23B00008008387E3 /* ViewModel.swift in Sources */,
|
||||
1ABFB8C223AFF5CC003D807E /* ContentView.swift in Sources */,
|
||||
);
|
||||
|
|
|
@ -1,29 +1,42 @@
|
|||
import SwiftUI
|
||||
import Combine
|
||||
import common
|
||||
|
||||
|
||||
struct ContentView: View {
|
||||
@StateObject var peopleInSpaceViewModel = PeopleInSpaceViewModel(repository: PeopleInSpaceRepository())
|
||||
@StateObject var viewModel = PeopleInSpaceViewModel(repository: PeopleInSpaceRepository())
|
||||
|
||||
var body: some View {
|
||||
TabView {
|
||||
PeopleListView(viewModel: viewModel)
|
||||
.tabItem {
|
||||
Label("People", systemImage: "person")
|
||||
}
|
||||
ISSMapView(issPosition: $viewModel.issPosition)
|
||||
.tabItem {
|
||||
Label("Map", systemImage: "location")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PeopleListView: View {
|
||||
@ObservedObject var viewModel: PeopleInSpaceViewModel
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
VStack {
|
||||
HStack {
|
||||
Text(peopleInSpaceViewModel.issPositionString)
|
||||
}
|
||||
.padding(EdgeInsets(top: 18, leading: 16, bottom: 0, trailing: 16))
|
||||
|
||||
VStack {
|
||||
|
||||
List(peopleInSpaceViewModel.people, id: \.name) { person in
|
||||
NavigationLink(destination: PersonDetailsView(peopleInSpaceViewModel: peopleInSpaceViewModel, person: person)) {
|
||||
PersonView(peopleInSpaceViewModel: self.peopleInSpaceViewModel, person: person)
|
||||
List(viewModel.people, id: \.name) { person in
|
||||
NavigationLink(destination: PersonDetailsView(viewModel: viewModel, person: person)) {
|
||||
PersonView(viewModel: viewModel, person: person)
|
||||
}
|
||||
}
|
||||
.navigationBarTitle(Text("People In Space"))
|
||||
.onAppear {
|
||||
self.peopleInSpaceViewModel.startObservingPeopleUpdates()
|
||||
viewModel.startObservingPeopleUpdates()
|
||||
}.onDisappear {
|
||||
self.peopleInSpaceViewModel.stopObservingPeopleUpdates()
|
||||
viewModel.stopObservingPeopleUpdates()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,12 +44,12 @@ struct ContentView: View {
|
|||
}
|
||||
|
||||
struct PersonView: View {
|
||||
var peopleInSpaceViewModel: PeopleInSpaceViewModel
|
||||
var viewModel: PeopleInSpaceViewModel
|
||||
var person: Assignment
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
ImageView(withURL: peopleInSpaceViewModel.getPersonImage(personName: person.name), width: 64, height: 64)
|
||||
ImageView(withURL: viewModel.getPersonImage(personName: person.name), width: 64, height: 64)
|
||||
VStack(alignment: .leading) {
|
||||
Text(person.name).font(.headline)
|
||||
Text(person.craft).font(.subheadline)
|
||||
|
@ -47,7 +60,7 @@ struct PersonView: View {
|
|||
|
||||
|
||||
struct PersonDetailsView: View {
|
||||
var peopleInSpaceViewModel: PeopleInSpaceViewModel
|
||||
var viewModel: PeopleInSpaceViewModel
|
||||
var person: Assignment
|
||||
|
||||
var body: some View {
|
||||
|
@ -55,9 +68,9 @@ struct PersonDetailsView: View {
|
|||
VStack(alignment: .center, spacing: 32) {
|
||||
Text(person.name).font(.title)
|
||||
|
||||
ImageView(withURL: peopleInSpaceViewModel.getPersonImage(personName: person.name), width: 240, height: 240)
|
||||
ImageView(withURL: viewModel.getPersonImage(personName: person.name), width: 240, height: 240)
|
||||
|
||||
Text(peopleInSpaceViewModel.getPersonBio(personName: person.name)).font(.body)
|
||||
Text(viewModel.getPersonBio(personName: person.name)).font(.body)
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import Foundation
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
import common
|
||||
|
||||
|
||||
struct ISSMapView: View {
|
||||
@Binding var issPosition: IssPosition
|
||||
|
||||
var body: some View {
|
||||
let issCoordinatePosition = CLLocationCoordinate2D(latitude: issPosition.latitude, longitude: issPosition.longitude)
|
||||
let regionBinding = Binding<MKCoordinateRegion>(
|
||||
get: {
|
||||
MKCoordinateRegion(center: issCoordinatePosition, span: MKCoordinateSpan(latitudeDelta: 150, longitudeDelta: 150))
|
||||
},
|
||||
set: { _ in }
|
||||
)
|
||||
VStack {
|
||||
Text("\(issPosition.latitude), \(issPosition.longitude)")
|
||||
Map(coordinateRegion: regionBinding, showsUserLocation: true,
|
||||
annotationItems: [ Location(coordinate: issCoordinatePosition) ]) { (location) -> MapPin in
|
||||
MapPin(coordinate: location.coordinate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct Location: Identifiable {
|
||||
let id = UUID()
|
||||
let coordinate: CLLocationCoordinate2D
|
||||
}
|
||||
|
||||
struct MapView: View {
|
||||
let issPosition: IssPosition
|
||||
let region: Binding<MKCoordinateRegion>
|
||||
|
||||
var body: some View {
|
||||
Map(coordinateRegion: region, showsUserLocation: true,
|
||||
annotationItems: [ Location(coordinate: .init(latitude: issPosition.latitude, longitude: issPosition.longitude)) ]) { (location) -> MapPin in
|
||||
MapPin(coordinate: location.coordinate)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ import common
|
|||
|
||||
class PeopleInSpaceViewModel: ObservableObject {
|
||||
@Published var people = [Assignment]()
|
||||
@Published var issPositionString = ""
|
||||
@Published var issPosition = IssPosition(latitude: 0, longitude: 0)
|
||||
|
||||
private var subscription: AnyCancellable?
|
||||
|
||||
|
@ -14,8 +14,8 @@ class PeopleInSpaceViewModel: ObservableObject {
|
|||
self.repository = repository
|
||||
|
||||
subscription = IssPositionPublisher(repository: repository)
|
||||
.map { position in String(format: "ISS Position = (%f, %f)", position.latitude, position.longitude ) }
|
||||
.assign(to: \.issPositionString, on: self)
|
||||
//.map { position in String(format: "ISS Position = (%f, %f)", position.latitude, position.longitude ) }
|
||||
.assign(to: \.issPosition, on: self)
|
||||
}
|
||||
|
||||
func startObservingPeopleUpdates() {
|
||||
|
|
Loading…
Reference in a new issue