1
1
import Foundation
2
2
import os. log
3
3
4
- #if canImport(Combine)
5
- import Combine
6
- #endif
7
-
8
4
internal extension URL {
9
5
enum Mensa {
10
6
static let baseUrl = URL ( string: " https://api.studentenwerk-dresden.de/openmensa/v2/ " ) !
@@ -15,138 +11,40 @@ internal extension URL {
15
11
}
16
12
}
17
13
18
- extension URLSession {
19
- fileprivate func emealDataTask( with url: URL , completion: @escaping ( Result < Data , EmealError > ) -> Void ) {
20
- let task = self . dataTask ( with: url) { data, response, error in
21
- guard
22
- let data = data,
23
- error == nil
24
- else {
25
- if let urlError = error {
26
- completion ( . failure( . other( urlError) ) )
27
- return
28
- }
29
- completion ( . failure( . unknown) )
30
- return
31
- }
32
- completion ( . success( data) )
33
- }
34
- task. resume ( )
35
- }
36
- }
37
-
38
14
// MARK: - Canteens
39
15
40
16
extension Canteen {
41
- public static func all( session: URLSession = . shared,
42
- completion: @escaping ( Result < [ Canteen ] , EmealError > ) -> Void ) {
43
- Logger . emealKit. debug ( " Creating data task for all canteens " )
44
- session. emealDataTask ( with: URL . Mensa. canteens) { result in
45
- switch result {
46
- case . failure( let error) :
47
- Logger . emealKit. error ( " Failed to fetch canteen data: \( String ( describing: error) ) " )
48
- completion ( . failure( error) )
49
- case . success( let data) :
50
- do {
51
- let canteens = try JSONDecoder ( ) . decode ( [ Canteen ] . self, from: data)
52
- Logger . emealKit. debug ( " Successfully fetched \( canteens. count) canteens " )
53
- completion ( . success( canteens) )
54
- } catch let error {
55
- Logger . emealKit. error ( " Failed to decode Canteen data: \( String ( describing: error) ) " )
56
- completion ( . failure( . other( error) ) )
57
- }
58
- }
59
- }
60
- }
61
-
62
- @available ( macOS 12 . 0 , iOS 15 . 0 , * )
63
- public static func all( session: URLSession = . shared) async throws -> [ Canteen ] {
64
- try await withCheckedThrowingContinuation { continuation in
65
- Self . all ( session: session) { result in
66
- continuation. resume ( with: result)
67
- }
17
+ public static func all( session: URLSession = . shared) async throws ( EmealError) -> [ Canteen ] {
18
+ Logger . emealKit. debug ( " Fetching all canteens " )
19
+ do {
20
+ let ( data, _) = try await session. data ( from: URL . Mensa. canteens)
21
+ let canteens = try JSONDecoder ( ) . decode ( [ Canteen ] . self, from: data)
22
+ Logger . emealKit. debug ( " Successfully fetched \( canteens. count) canteens " )
23
+ return canteens
24
+ } catch ( let error) {
25
+ Logger . emealKit. error ( " Failed to fetch canteen data: \( String ( describing: error) ) " )
26
+ throw . other( error)
68
27
}
69
28
}
70
29
}
71
30
72
- #if canImport(Combine)
73
- extension Canteen {
74
- public static func allPublisher( session: URLSession = . shared) -> AnyPublisher < [ Canteen ] , EmealError > {
75
- session. dataTaskPublisher ( for: URL . Mensa. canteens)
76
- . map { $0. data }
77
- . decode ( type: [ Canteen ] . self, decoder: JSONDecoder ( ) )
78
- . mapError { EmealError . other ( $0) }
79
- . receive ( on: DispatchQueue . main)
80
- . eraseToAnyPublisher ( )
81
- }
82
- }
83
- #endif
84
-
85
31
// MARK: - Meals
86
32
87
33
extension Meal {
88
- public static func `for`( canteen: CanteenId ,
89
- on date: Date ,
90
- session: URLSession = . shared,
91
- completion: @escaping ( Result < [ Meal ] , EmealError > ) -> Void ) {
92
- Self . for ( canteen: canteen. rawValue, on: date, session: session, completion: completion)
93
- }
94
-
95
- public static func `for`( canteen: Int ,
96
- on date: Date ,
97
- session: URLSession = . shared,
98
- completion: @escaping ( Result < [ Meal ] , EmealError > ) -> Void ) {
99
- Logger . emealKit. debug ( " Creating data task for canteen \( canteen) on \( date) " )
100
- session. emealDataTask ( with: URL . Mensa. meals ( canteen: canteen, date: date) ) { result in
101
- switch result {
102
- case . failure( let error) :
103
- Logger . emealKit. error ( " Failed to fetch meal data: \( String ( describing: error) ) " )
104
- completion ( . failure( error) )
105
- case . success( let data) :
106
- do {
107
- let meals = try JSONDecoder ( ) . decode ( [ Meal ] . self, from: data)
108
- Logger . emealKit. debug ( " Successfully fetched \( meals. count) meals " )
109
- completion ( . success( meals) )
110
- } catch let error {
111
- Logger . emealKit. error ( " Failed to decode meal data: \( String ( describing: error) ) " )
112
- completion ( . failure( . other( error) ) )
113
- }
114
- }
34
+ public static func `for`( canteen: Int , on date: Date , session: URLSession = . shared) async throws ( EmealError) -> [ Meal ] {
35
+ Logger . emealKit. debug ( " Fetching meals for canteen \( canteen) on \( date) " )
36
+ do {
37
+ let ( data, _) = try await session. data ( from: URL . Mensa. meals ( canteen: canteen, date: date) )
38
+ let meals = try JSONDecoder ( ) . decode ( [ Meal ] . self, from: data)
39
+ Logger . emealKit. debug ( " Successfully fetched \( meals. count) meals " )
40
+ return meals
41
+ } catch ( let error) {
42
+ Logger . emealKit. error ( " Failed to fetch meal data: \( String ( describing: error) ) " )
43
+ throw . other( error)
115
44
}
116
45
}
117
46
118
- @available ( macOS 12 . 0 , iOS 15 . 0 , * )
119
- public static func `for`( canteen: CanteenId , on date: Date , session: URLSession = . shared) async throws -> [ Meal ] {
47
+ public static func `for`( canteen: CanteenId , on date: Date , session: URLSession = . shared) async throws ( EmealError) -> [ Meal ] {
120
48
try await Self . for ( canteen: canteen. rawValue, on: date, session: session)
121
49
}
122
-
123
- @available ( macOS 12 . 0 , iOS 15 . 0 , * )
124
- public static func `for`( canteen: Int , on date: Date , session: URLSession = . shared) async throws -> [ Meal ] {
125
- try await withCheckedThrowingContinuation { continuation in
126
- Self . for ( canteen: canteen, on: date, session: session) { result in
127
- continuation. resume ( with: result)
128
- }
129
- }
130
- }
131
- }
132
-
133
- #if canImport(Combine)
134
- extension Meal {
135
- public static func publisherFor( canteen: Int ,
136
- on date: Date ,
137
- session: URLSession = . shared) -> AnyPublisher < [ Meal ] , EmealError > {
138
- session. dataTaskPublisher ( for: URL . Mensa. meals ( canteen: canteen, date: date) )
139
- . map { $0. data }
140
- . decode ( type: [ Meal ] . self, decoder: JSONDecoder ( ) )
141
- . mapError { EmealError . other ( $0) }
142
- . receive ( on: DispatchQueue . main)
143
- . eraseToAnyPublisher ( )
144
- }
145
-
146
- public static func publisherFor( canteen: CanteenId ,
147
- on date: Date ,
148
- session: URLSession = . shared) -> AnyPublisher < [ Meal ] , EmealError > {
149
- Self . publisherFor ( canteen: canteen. rawValue, on: date, session: session)
150
- }
151
50
}
152
- #endif
0 commit comments