carson-katri / swift-request

Declarative HTTP networking, designed for SwiftUI
MIT License
730 stars 41 forks source link

Please add working examples #12

Closed sworteu closed 5 years ago

sworteu commented 5 years ago

Can you add a working example of this library? I can’t get it to work.

carson-katri commented 5 years ago

Hi! I can definitely add an example. In the meantime, you can take a look at reddit-swiftui, which uses it. Also if you can show me what you've tried, maybe I can point you in the right direction?

sworteu commented 5 years ago

Wil let you know as soon as possible if i get it working. Did you try to have apple implement this natively? It seems really to be a missing feature. Awsome thinking and work.

carson-katri commented 5 years ago

No, I haven't tried to do that. I guess if I wanted to do something like that I could make a PR to https://github.com/apple/swift-corelibs-foundation with an implementation in URLSession

sworteu commented 5 years ago

The reddit version does work. What i'm getting is errors (won't build) cause of:

Unable to infer complex closure return type; add explicit type to disambiguate Or Cannot convert value of type 'Text' to closure result type 'TupleView<(Any, Any)>'

So i'm having a view: struct CoinsView: View { var body: some View { RequestView(StatsResponse.self, Request { Url("https://api.blockchain.info/stats") Method(.get) Header.Accept(.json) }) { statsresponse in Text("Hello world") } } }

With the following struct: struct StatsResponse: Decodable, Identifiable { let id: UUID = UUID() let market_price_usd: Double let hash_rate: Double let minutes_between_blocks: Double let estimated_transaction_volume_usd: Double let miners_revenue_usd: Double let trade_volume_btc: Double let trade_volume_usd: Double let total_fees_btc: Int let n_btc_mined: Int let n_tx: Int let n_blocks_mined: Int let totalbc: Int let n_blocks_total: Int let blocks_size: Int let nextretarget: Int let difficulty: Int let estimated_btc_sent: Int let miners_revenue_btc: Int let total_btc_sent: Int let timestamp: Int }

and my contentView contains (the main view) struct ContentView: View { var body: some View { CoinsView() } }

i tried alot of combinations as per-docs and as in the reddit example, it keeps erroring. Not sure what i'm missing here.

I want a list with all those values. Had it working but it showed no content (only print(statsresponse) it would print:

StatsResponse( .... ALL KEY / VALUES .... ) So it DOES work but it keeps complaining when using the values in my views

.onObject is what i want to use. Thanks.

carson-katri commented 5 years ago

You were so close! You just forgot the placeholder in the RequestView for when it is loading:

struct CoinsView: View {
    var body: some View {
        RequestView(StatsResponse.self, Request {
            Url("https://api.blockchain.info/stats")
            Method(.get)
            Header.Accept(.json)
        }) { statsresponse in
            Text(statsresponse != nil ? "\(statsresponse!.estimated_btc_sent)" : "")
            Text("Loading...")
        }
    }
}

You can see I added below your Text("Hello World") (which I changed to show some retrieved data) a Text("Loading..."). This shows while the request is being performed. In the case of the Reddit app, I made a SpinnerView for loading. You could do something similar, or just use Text or a clear Rectangle, doesn't really matter.

sworteu commented 5 years ago

Hi thanks @carson-katri I’s not that well explained in the guide so i missed that. It seems very nice how simple this is once you get the hang of it. It’s maybe the error text saying something that don’t seem to make it clear what was missing!

Thank you for your time! Case closed

carson-katri commented 5 years ago

Glad it worked! Can’t wait to see what you make with it. I’ll see if I can improve the guide. A lot of SwiftUI’s error messages are confusing if you don’t know it well enough. I may even make it so you don’t have to provide a loading view.

sworteu commented 5 years ago

Can you give a short note how to use it with array objects the right way?

RequestView( [ToDos].self, Request { Url("https://someapi.returing.a.json.string.array/") Header.Accept(.json) Method(.get) }) { todos in List(todos != nil ? todos{ $0.id } : [] ) { todo in Text("Data: \(todo)") } SpinnerView() }

What's the best way to do this? The AnyRequest<[Todos]> is also not working for me. i want to parse a json: ["item1", "item2"] array there is only an array returned no json objects.

not sure how the struct should be something like?: struct Todos: Codable, Identifiable { let id: UUID = UUID() let title: String } This is not working for me as xcode is again complaining identifiable

i'm using xcode 11 beta 7 by the way (At ObservableObject was changed (deprecated)) they now use "@Published" ..

carson-katri commented 5 years ago

So you're trying to retrieve an array of Strings, or an array of JSON objects? If it's an array of Strings, can you point me to an API that responds with that so I can try to get something working?

sworteu commented 5 years ago

https://api.myjson.com/bins/17msc3 hope you'll get something out of it..;) thanks again.

carson-katri commented 5 years ago

Here's a simple example:

struct ContentView: View {
    var body: some View {
        RequestView([String].self, Request {
            Url("https://api.myjson.com/bins/17msc3")
        }) { items in
            List(items ?? [], id: \.self) { item in
                Text(item)
            }
            Text("Loading...")
        }
    }
}
sworteu commented 5 years ago

You are amazing dude. That's insanity, works flawless!

Ok so if our apps are done, you want a linkback to a site?

carson-katri commented 5 years ago

Happy to help! Just a link to the repo or the repo name somewhere in the app with any of the other open source packages you all used is fine.