Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/docs-dryrun.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ jobs:
runs-on: macos-15
steps:
- name: Checkout main
uses: actions/checkout@v4
uses: actions/checkout@v6
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/setup-python@v4
- uses: actions/setup-python@v6
with:
python-version: 3.x
- name: Prepare dependencies
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ jobs:
runs-on: macos-15
steps:
- name: Checkout main
uses: actions/checkout@v4
uses: actions/checkout@v6
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/setup-python@v4
- uses: actions/setup-python@v6
with:
python-version: 3.x
- name: Prepare dependencies
Expand All @@ -34,7 +34,7 @@ jobs:
./docs.sh

- name: Deploy docs
uses: peaceiris/actions-gh-pages@v3
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
26 changes: 12 additions & 14 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,19 @@ jobs:
matrix:
include:
- os: macos-26
xcode: "26.1.1"
xcode: "26.4"
- os: macos-15
xcode: "26.1.1"
xcode: "26.3"
- os: macos-15
xcode: "16.4"
- os: macos-14
xcode: "16.1" # sic, 16.2 not available on GitHub as of Jan 2025

runs-on: ${{ matrix.os }}

steps:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ matrix.xcode }}
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Build
run: swift build --target TripKit

Expand All @@ -47,12 +45,12 @@ jobs:

strategy:
matrix:
swift: ["6.1", "6.0", "5.10"]
swift: ["6.2", "6.1", "6.0", "5.10"]
container:
image: swift:${{ matrix.swift }}

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Build
run: swift build --target TripKitAPI

Expand All @@ -63,13 +61,13 @@ jobs:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/checkout@v3
- uses: actions/checkout@v6
- name: Build TripKit Mac
run: set -o pipefail && xcodebuild build -project TripKit.xcodeproj -scheme "TripKit" -sdk macosx | xcbeautify
- name: Build TripKitUI iOS
run: set -o pipefail && xcodebuild build -project TripKit.xcodeproj -scheme "TripKitUI" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 16' | xcbeautify
run: set -o pipefail && xcodebuild build -project TripKit.xcodeproj -scheme "TripKitUI" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 17' | xcbeautify
- name: Build TripKitInterApp iOS
run: set -o pipefail && xcodebuild build -project TripKit.xcodeproj -scheme "TripKitInterApp" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 16' | xcbeautify
run: set -o pipefail && xcodebuild build -project TripKit.xcodeproj -scheme "TripKitInterApp" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 17' | xcbeautify

test_xcode:
runs-on: macos-15
Expand All @@ -78,12 +76,12 @@ jobs:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Run tests
env:
TRIPGO_API_KEY: ${{ secrets.TRIPGO_API_KEY }}
run: |
set -o pipefail && xcodebuild test -project TripKit.xcodeproj -scheme "TripKit" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 16' | xcbeautify
set -o pipefail && xcodebuild test -project TripKit.xcodeproj -scheme "TripKit" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 17' | xcbeautify

example_spm:
runs-on: macos-15
Expand All @@ -92,6 +90,6 @@ jobs:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Build TripKitUIExample
run: set -o pipefail && xcodebuild build -project TripKit.xcodeproj -scheme TripKitUIExample -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 16' | xcbeautify
run: set -o pipefail && xcodebuild build -project TripKit.xcodeproj -scheme TripKitUIExample -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 17' | xcbeautify
16 changes: 8 additions & 8 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/ReactiveX/RxSwift.git", .upToNextMajor(from: "6.1.0")),
.package(url: "https://github.com/onevcat/Kingfisher.git", .upToNextMajor(from: "8.0.0")),
.package(url: "https://github.com/skedgo/GeoMonitor.git", .upToNextMinor(from: "0.2.0")),
.package(url: "https://github.com/skedgo/GeoMonitor.git", .upToNextMinor(from: "0.3.0")),
// .package(url: "https://github.com/skedgo/TGCardViewController.git", branch: "ios26"),
.package(url: "https://github.com/skedgo/TGCardViewController.git", .upToNextMajor(from: "2.4.0")),
],
Expand Down
22 changes: 17 additions & 5 deletions Sources/TripKit/server/parsing/TKAPIToCoreDataConverter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -291,16 +291,28 @@ extension Shape {

// add the stops
if let service = current {
// remember the existing visits
var existingVisitsByCode: [String: StopVisits] = [:]
// Remember the existing visits. We group repeated stop codes into a
// list sorted by visit index, so loop services consume matching visits
// in route order instead of reusing the same visit object each time.
var existingVisitsByCode: [String: [StopVisits]] = [:]
let visits = (current?.visits ?? []).filter { !($0 is DLSEntry) }
for visit in visits {
existingVisitsByCode[visit.stop.stopCode] = visit
existingVisitsByCode[visit.stop.stopCode, default: []].append(visit)
}
existingVisitsByCode = existingVisitsByCode.mapValues { $0.sorted() }

func nextExistingVisit(for stopCode: String) -> StopVisits? {
guard var candidates = existingVisitsByCode[stopCode], !candidates.isEmpty else {
return nil
}
let match = candidates.removeFirst()
existingVisitsByCode[stopCode] = candidates
return match
}

for apiStop in apiShape.stops {
let visit: StopVisits
if let existing = existingVisitsByCode[apiStop.code] {
if let existing = nextExistingVisit(for: apiStop.code) {
visit = existing
} else {
visit = StopVisits(context: context)
Expand All @@ -314,7 +326,7 @@ extension Shape {
// hook-up to shape
shape.addToVisits(visit)

if !existingVisitsByCode.keys.contains(apiStop.code) {
if visit.stop == nil {
let coordinate = TKNamedCoordinate(latitude: apiStop.lat, longitude: apiStop.lng, name: apiStop.name, address: nil)
let stop = StopLocation.fetchOrInsertStop(stopCode: apiStop.code, modeInfo: modeInfo, at: coordinate, in: context)
stop.shortName = apiStop.shortName
Expand Down
2 changes: 1 addition & 1 deletion Sources/TripKitUI/managers/TKUITripMonitorManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public class TKUITripMonitorManager: NSObject, ObservableObject {
} onEvent: { [weak self] event in
guard let self, let monitoredTrip = self.monitoredTrip else { return }
switch event {
case .entered(let region, _):
case .entered(let region, _), .foreground(let region, _):
guard let match = monitoredTrip.notifications.first(where: { $0.id == region.identifier }) else { return }
self.notify(with: match, trigger: nil) // Fire right away
case .manual(let region, let location):
Expand Down
23 changes: 23 additions & 0 deletions Tests/TripKitTests/Data/departures-darwin-loop.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"embarkationStops": [
{
"stopCode": "046",
"services": [
{
"startTime": 1775711400,
"serviceTripID": "675194105_B506",
"serviceName": "Casuarina to Casuarina - via Wanguri, Lyons, Muirhead",
"serviceDirection": "Casuarina to Casuarina - via Wanguri, Lyons, Muirhead",
"serviceNumber": "24",
"operatorID": "au-nt-cdc-CDC",
"operator": "CDC",
"modeInfo": {
"identifier": "pt_pub_bus",
"alt": "bus",
"localIcon": "bus"
}
}
]
}
]
}
58 changes: 58 additions & 0 deletions Tests/TripKitTests/Data/service-darwin-loop.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"shapes": [
{
"travelled": true,
"encodedWaypoints": "abc",
"serviceTripID": "675194105_B506",
"serviceName": "Casuarina to Casuarina - via Wanguri, Lyons, Muirhead",
"serviceDirection": "Casuarina to Casuarina - via Wanguri, Lyons, Muirhead",
"serviceNumber": "24",
"operator": "CDC",
"operatorID": "au-nt-cdc-CDC",
"routeID": "24",
"wheelchairAccessible": true,
"stops": [
{
"lat": -12.37375,
"lng": 130.88327,
"code": "046",
"name": "Trower Rd after Linton St",
"wheelchairAccessible": true,
"departure": 1775711400
},
{
"lat": -12.37213,
"lng": 130.88206,
"code": "047",
"name": "9 Scaturchio St",
"wheelchairAccessible": true,
"arrival": 1775711460,
"departure": 1775711460
},
{
"lat": -12.37693,
"lng": 130.88581,
"code": "144",
"name": "28 Vanderlin Dve",
"wheelchairAccessible": true,
"arrival": 1775712900,
"departure": 1775712900
},
{
"lat": -12.37375,
"lng": 130.88327,
"code": "046",
"name": "Trower Rd after Linton St",
"wheelchairAccessible": true,
"arrival": 1775712960,
"departure": 1775712960
}
]
}
],
"modeInfo": {
"identifier": "pt_pub_bus",
"alt": "bus",
"localIcon": "bus"
}
}
Loading
Loading