alexander-albers / tripkit Goto Github PK
View Code? Open in Web Editor NEWSwift library for querying data from public transport providers.
License: MIT License
Swift library for querying data from public transport providers.
License: MIT License
It seems like since Xcode 13 NSKeyedUnarchiver complains about certain data types when decoding a saved object.
Example:
xctest[16883:503835] [general] *** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSNumber' (0x7ff84cc674e8) [/System/Library/Frameworks/Foundation.framework]' for key 'priority', even though it was not explicitly included in the client allowed classes set: '{(
"'NSArray' (0x7ff84cc3d970) [/System/Library/Frameworks/CoreFoundation.framework]",
"'TripKit.SuggestedLocation' (0x10dd72a00) [/Users/alex/Library/Developer/Xcode/DerivedData/TripKit-dsfwcedxwupmylaklfxshubrnyjl/Build/Products/Debug/TripKit.framework]"
)}'. This will be disallowed in the future.
Efa:
tripkit/Sources/TripKit/AbstractEfaProvider.swift
Line 1547 in e8d7236
Sometimes the query trips method returns a no-internet-connection error when querying a trip with coordinate locations.
At the moment you can send a refresh trip request to efa based providers, but delays won't get recalculated.
Provide a set of enum values to check which parameters and methods each network provider supports.
Example enum: supports max changes parameter
Under some circumstances, initializing a NSAttributedString from a HTML string in a background thread may cause a crash. See discussion in Apple Docs: https://developer.apple.com/documentation/foundation/nsattributedstring/1524613-init
Relevant code in project:
tripkit/Sources/TripKit/Util/ParserUtils.swift
Lines 44 to 68 in 7b1f15a
Since this is used to strip out any html tags and parse things such as ordered and unordered lists, this method could potentially be rewritten without any use of NSAttributedString.
Currently, every unhandled remark or message is appended to the message text of a leg. The intention behind this was to not withhold any important information from the user. However at the moment way too many unnecessary information is being parsed, like the operator of the mot or mask mandates. On the other side, delay reasons like "Reparatur am Zug" might not be parsed at all.
The approach of for example the VBB app is to only parse around 10-20 remarks and show messages like the mask mandate only once per trip. The problem with this approach is that there are way too many remark types that could be parsed, so you have to make a selection without withholding key information (db, for instance, displays some text of the remarks-array below the trip leg).
Related issues are public-transport/hafas-client#5 and marudor/bahn.expert#139.
Todos for now:
Sending a trip request may fail with invalid location
. It seems like the wrong location type is supplied for pois.
Example: suburbID%3A14628130%3A50%3AGlash%C3%BCtte (Sachs)%3A1533682%3A5405107%3AMRCV
will not be identified, because TripKit uses type=address instead of type=any.
May be because location is supplied from ambiguous results.
The currently used VGN server will shut down soon (30. Sept. 2021). A new endpoint is available at DEFAS, https://vgn.defas-fgi.de/vgnExt/, but all current station ids won't be compatible anymore.
The HAFAS endpoint hvv-app.hafas.de may be shut down at the end of 2021. Currently, search requests to the API contain a warning that the "App version will be switched off on 1.1.2022".
The new website and app of HVV use Geofox.de as API provider.
{
"version": 47,
"language": "de",
"start": {
"name": "Hauptbahnhof",
"city": "",
"combinedName": "",
"type": "STATION",
"id": "Master:9910950"
},
"dest": {
"name": "Berliner Platz",
"city": "",
"combinedName": "",
"type": "STATION",
"id": "Master:62003"
},
"toStartBy": "FOOTPATH",
"toDestBy": "FOOTPATH",
"time": {
"date": "04.12.2021",
"time": "09:54"
},
"timeIsDeparture": true,
"schedulesBefore": 0,
"schedulesAfter": 4,
"intermediateStops": true,
"tariffInfoSelector": [
{
"tariff": "HVV",
"tariffRegions": true,
"kinds": [
"1"
]
},
{
"tariff": "SH",
"tariffRegions": false,
"kinds": [
"1"
]
}
],
"penalties": [
{
"name": "desiredType",
"value": "longdistancebus,fasttrain&extrafasttrain:10000"
}
],
"returnContSearchData": true,
"realtime": "REALTIME"
}
Authentication:
geofox-auth-user: hbtweb
geofox-auth-signature: base64(HmacSHA1(request_body, pass))
In AVV Aachen, sometimes the name of the place is just "AC" instead of "Aachen".
While the official Website still uses the EFA endpoint, the GVH App now uses a hafas backend (gvh.hafas.de) and seems to return way more accurate data.
When querying for trips around midnight time, sometimes trips get shown with a delay of 1440 minutes. This seems to be caused by some day rollover bug, probably only for trips in Bonn.
Example trip: Arndstr. -> Bonn Hbf
It would be nice if all model classes (ie. everything in the model package like Trip, Leg, Departure and so on) would be a struct instead of a class. That way we could remove a lot of boilerplate since structs in Swift automatically support serialization, hashing etc. One caveat is that the new structs must be able to decode data that has been previously encoded using the current classes. Otherwise, previously saved data is lost.
Also, there is a lot of potential for cleaning up all variable and method names. We should:
All points above are medium term goals to make the API a little nicer to use for everyone. :)
BSV returns "Ersatzhalt nördlich der Kreuzung". Ideally, this information shouldn't be parsed as a platform.
Even though I'm not a fan of using many third party frameworks, SwiftyJson does a great job of keeping the code clean and readable when dealing with Json responses, while still keeping type-safety. That's why I'd like to expand the usage of SwiftyJson to more network provider implementations.
Add (additional) api methods that support the async/await pattern that has been introduced with Swift 5.5.
Resources:
When using suggestLocations for eg. "Goldbachstraße", two results appear. Only one of them is valid and can be used for queryDepartures, the other one does not seem to work.
BVG requires, for whatever reason, that the product type "BERLKOENIG" is included, or otherwise some trips may fail, even if those don't include any Berlkönig products.
See for example this request:
{
"auth": {
"aid": <secret>,
"type": "AID"
},
"svcReqL": [
{
"meth": "TripSearch",
"cfg": {},
"req": {
"arrLocL": [
{
"type": "S",
"lid": "A=1@O=U Elsterwerdaer Platz (Berlin)@X=13560758@Y=52504644@U=86@L=900171006@B=1@p=1617247685@"
}
],
"getPolyline": true,
"gisFltrL": [
{
"type": "M",
"meta": "foot_speed_normal",
"profile": {
"linDistRouting": false,
"maxdist": 2000,
"type": "F"
},
"mode": "FB"
}
],
"depLocL": [
{
"lid": "A=1@O=Pilgramer Str./Rahnsdorfer Str. (Berlin)@X=13619395@Y=52496554@U=86@L=900176540@B=1@p=1617247685@",
"type": "S"
}
],
"outFrwd": true,
"outTime": "080000",
"extChgTime": -1,
"getPasslist": true,
"trfReq": {
"jnyCl": 2,
"tvlrProf": [
{
"type": "E"
}
],
"cType": "PK"
},
"jnyFltrL": [
{
"value": "1111111111",
"mode": "BIT",
"type": "PROD"
},
{
--> "value": "BERLKOENIG",
"mode": "INC",
"type": "GROUP"
}
],
"outDate": "20210409"
}
}
],
"ext": "BVG.1",
"formatted": true,
"lang": "de",
"ver": "1.24",
"client": {
"id": "BVG",
"type": "IPH",
}
}
However, enabling this option leads to a new JNY-type named "KISS", which is currently not handled and results in a parse error.
--> Revert this commit after KISS is handled: b04f52c
queryTrips may use the wrong location when supplying a point-of-interest. For example, Uniklinik Köln is a POI which has the same location id as "Köln-Aachener Str., Elsdorf".
Currently, all tests only support one specific trip or departure stop that will be tested. Ideally, we should be able to specify all locations in some kind of array to be able to test several specific trips.
For example, for the BVG provider it would be nice to additionally test a journey where the Berlkönig flag is required (see #26), while still keeping the current test trip.
We could for example specify all trips that should be tested like the following in a provider test class:
var trips: [
["900013103", "900056102"], // from Prinzenstraße to Nollendorfplatz
["1", "2", "3"], // from 1 to 3 via 2
//...
]
var departures: [
"900013103", // test departures for Prinzenstraße
"900056102", // test departures for Nollendorfplatz
//...
]
When querying trips using non-latin characters, there exists a problem where the response locations cannot be parsed anymore by the library.
Example:
Provider: RMV
From: Schöfferstraße 2, 达姆施塔特 (4-49867186:8640047)
To: Wormser Straße 32, 64295 达姆施塔特, 德国 (3-49856719:8637645)
Response location is Schöfferstraße 2,
, where the second location part is empty and reversed - usually, the place is first.
This results in a parse error, as we try to create a location with a place name but no location name.
Some providers require url encoding or decoding using non-utf8 charsets. This behavior has been deprecated by Apple for some years now.
tripkit/Sources/TripKit/Util/HttpClient.swift
Lines 179 to 189 in d9a95d5
Those methods already have been removed from the Swift String class and are only available for NSString:
https://github.com/apple/swift-corelibs-foundation/blob/eec4b26deee34edb7664ddd9c1222492a399d122/Sources/Foundation/NSStringAPI.swift#L2165
Deprecation warning for NSString: Use -stringByRemovingPercentEncoding instead, which always uses the recommended UTF-8 encoding.
decodeUrl
encodeUrl
Currently, everything still works fine, but this url encoding/decoding may need to be reimplemented at some point in the future if Apple decides to completely remove the respective methods.
Line numbers from VMV provider currently contain lots of unnecessary information, like the full product name (eg. Regional Express) or the provider name (eg. Ostdeutsche Eisenbahn GmbH).
Example: Schwerin, Hbf.
Issue was likely introduced with: bb31487
Add code documentation to all classes inside the model folder. Maybe slightly related to #17.
It seems like the departures query is broken. The VRS server merely returns an error response, see the following sample query:
http://android.vrsinfo.de/index.php?eID=tx_vrsinfo_ass2_timetable&r=50.946398,6.956496&s=10
{
"error": "Keine gültige ID"
}
The iOS app uses the eID=tx_ekap_here
instead, so I am planning to switch to this endpoint instead.
In some cases, having a Z
at the end of the timestamp causes the following error:
{ error: "Es wurden keine gültigen Verbindungen für diese Anfrage gefunden. ", host: "ASS3APPS" }
.
We should replace it with the correct time zone value, e.g. +0300
.
Previously, the VVM Mittelfranken provider has been used in VvmProvider.swift. The old endpoint was no longer reachable, and when I migrated the url to the current one, I confused VVM Mittelfranken with VVM Mainfranken and added the endpoint for the latter. Both providers use https://www.bayern-fahrplan.de on their website and are probably connected to DEFAS, but the VVM Mittelfranken app does not use the Efa or Hafas API. The question is how to move forward from now on.
As some station ids seem to be interoperable, I tend to just keep the current implementation of the VVM and continue only supporting the VVM Mainfranken for now..
VRN yields a session expired error when querying more trips.
Possibly only allows trips later and not earlier?
Use the default parameter language feature of Swift to specify some default values, eg. Date()
for time parameters or true
for departure parameters.
URL: https://www.westfalenfahrplan.de/std3/XSLT_TRIP_REQUEST2?language=de
Also used by moBiel
There are still journey types which are not being parsed in AbstractHciProvider and result in a parse error:
I haven't encountered any of the above mentioned types in the wild, except for one case: BVG requires that the product type "BERLKOENIG" is included, or otherwise some trips may fail, even if those don't include any Berlkönig products (see #26).
I'd love to add support for navitia providers as done in the public transport enabler.
Cannot get any connections with BVG.
Other providers work, but BVG doesn't.
In jny:
"polyG": {
"polyXL": [
0
],
"layerX": 0,
"crdSysX": 0
},
In common:
"polyL": [
{
"delta": true,
"dim": 2,
"crdEncYX": "coords",
"crdEncS": "NNMKNLNMNMNNLNNNKNNNMNMLNKNNN",
"crdEncF": "?????????????????????????????",
"ppLocRefL": [
{
"ppIdx": 0,
"locX": 0
},
{
"ppIdx": 13,
"locX": 3
},
{
"ppIdx": 28,
"locX": 2
}
]
},
...
]
Uses the HCI interface with mic/mac.
When querying trips for the current time, sometimes the first possible trip does not appear in the results (eg. queryTrips for 15:00 would not show a trip departuring at 15:01). May be correlated to the trip having a delay.
Possible workaround: query trips 10-15 minutes earlier.
http://appefa10.verbundlinie.at/android/ is currently no longer reachable and results in timeouts. It seems like they moved from Efa to Hafas.
The website now uses https://verkehrsauskunft.verbundlinie.at/bin/mgate.exe, while the app accesses https://app.verkehrsauskunft.at/bin/mgate.exe?mic=37cc32a073ae4f8632631e3e620b2305&mac=11d9b0dc281052e605c6a330797227d1.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.