Sequential Requests With Logic - Swift 3, Xcode 8, Alamofire 4 - ios

UPDATE: I a using SwiftEventBus https://github.com/cesarferreira/SwiftEventBus and this seems to work fine. I can simply define event listeners that wait on each step. Still interested in other approaches for multi-step login process.
I need to solve a multipart login process (stuck on how to wrap logic around serial GET/POST requests)
also on github as https://github.com/Alamofire/Alamofire/issues/1746
step 1 validate user/pw with basic authentication header
step 2 use returned token (from step 1) in new authentication header and
fetch from server a list
step 3 user selects from returned list (or does another request to
create new if thing not found on list) - note really important what
the list is because I am just interested in the serialization and
wrapping logic across steps
step 4 use guid from selected/created thing to generate auth token to
fetch yet another new general use auth token and refresh token
I can do each of these individually (set headers, set parms, validate and parse result, etc), BUT I do not understand how to create the logic flow around the requests. Do I have to nest all of the requests inside each other so that I step 2 happens inside step 1, step 3 happens inside step 2, etc. Or is there a simple example application somewhere that shows how execute multiple requests with logic around the requests - Not interested in simply queueing the requests as I have to run logic around the requests. Event Bus? Managed queue? Other? Looking for guidance and ideally a downloadable sample app that I can play with and learn from.
I originally built this without Alamofire and had the request timing/logic problem and thought Alamofire might make this easier but after switching to Alamofire I find myself stuck at the same point. Open to a suggestion without Alamofire in order to learn how to do this.

This is not build into Alamofire per se because it is callback based but you can use the callbacks and nest each call to Alamofire into the other like that:
Alamofire.request("url").responseJSON { _ in
Alamofire.request("anotherUrl").responseJSON { _ in
Alamofire.request("yetAnotherUrl").responseJSON { _ in
//all three have finished with either response or error
}
}
}
This leads to a pattern often seen with callbacks that is also sometimes referred to as Pyramid of doom.
As an alternative you can check out either Promises or I like to use a reactive library like RxSwift that will give your code more of a 'waterfall' look.
There is also a PromiseKit extension and a RxSwift extenstion for Alamofire.

Related

Fn project is missing http operations (CRUD)

I have spent my afternoon getting very excited about the container-native serverless platform 'fn project' - http://fnproject.io/.
I love the idea of the FaaS model but have no intention of locking myself into a particular cloud vendor for most of the lifetime of an app - and several other reasons including the desire to spin up the entire app on a small server anywhere if I choose.
fn project seems great for my needs until I finish perusing the documentation and all the relevant blog posts and suddenly think 'what? Wait....what??? Where are the http operations?'.
I cannot find a single reference anywhere that states if it is even possible to to have http triggers for different http operations (ie POST, PUT, PATCH, DELETE), let alone how I would do it.
I want to build REST api's (or certainly at the very least json-serving http-based RPC apis - if it doesn't have hypermedia links it isn't REST ;) but let's not get into that one in this thread)
Am I missing something here (certainly the correct bit of documentation)??
Can anybody please enlighten me as to how I would do this, or even tell me if I have totally misunderstood what I should use this for?
My excitement has gone soft for now but I'm hoping someone that will change with the right information.
It feels odd that I can't find anyone else complaining about this, so I think that indicates my misunderstanding perhaps.
Other solutions such as OpenFaaS look interesting but I dont wan't to have to learn how to deploy kubernetes and docker swarms if I can avoid it :)
I'm not an expert, but as of now it seems not possible to specify the http method inside the trigger. Check latest trigger spec : as you can see, there is no notion of http method here.
However, handling different HTTP methods can be done inside the function itself.
For example, in Java (with fdk-java v1.0.80), you can use com.fnproject.fn.api.httpgateway.HTTPGatewayContext as the first parameter of the function, as described in the section "Accessing HTTP Information From Functions" of the documentation :
In Fn for Java, when your function is being served by an HTTP trigger (or another compatible HTTP gateway) you can get access to both the incoming request headers for your function by adding a 'com.fnproject.fn.api.httpgateway.HTTPGatewayContext' parameter to your function's parameters.
Using this allows you to :
...
Access the method and request URL for the trigger
...
You can then retrieve the HTTP method by calling getMethod() on the HTTPGatewayContext passed as parameter.
In other languages (with others fdk), it's possible to do the same :
in Go : example calling RequestMethod() on context
in Ruby : class HTTPContext
in Python : class HTTPGatewayContext
in Node : class HTTPGatewayContext
From this different contexts, you'll then be able to get method parameter passed when fn invoke --method=[GET|POST|...] (via fn-http-method header).
The main drawback here is that all HTTP methods should be handled in the same function. Nonetheless, you can structure your code to have only one class per method.
After some further thought it seems fairly clear now what my actual misunderstanding was....
When I have built Serverless framework services in the past (or built and deployed Lambda functions using terraform) I have been deploying to AWS and so have been using AWS's API Gateway offering (their product is actually called API gateway but its important to recognise that API Gateway is a distributed systems / micro-sevices design pattern).
API gateway makes it possible to route specific http request types including the method (GET,POST,PUT,DELETE) to the desired functions.
Platforms such as Fn project and OpenFaaS do not provide an out of the box api gateway solution and it seems we would need to take care of this ourselves.
These above mentioned platforms are about deployment of functions. We find the other bits via our product of choice.

batch url execution with redstone

I am creating a rest api with redstone and dart.
Now I need to create a way to send several commands of the api in one POST.
Edit (#Pacane): Yes, the idea is to have one endpoint that can parse several commands within the api. Each command is another endpoint(Route) that can be accessed singularly within the API.
My question is how I can parse, executes the URLs and get the response for each URL using redstone.
I am thinking about using the unittest mock request and mock response. You can see here:
https://github.com/redstone-dart/redstone/wiki/Unit-test
Now I wonder if the mock request and response are different somehow from regular requests, if they use some analysis or something like it that would harm performance.
So, there are 2 questions:
1) is it ok to mock the redstone to parse several URLs?
2) if not, how could I do it?
thanks
I ended up using the MockRequest and MockResponse to achieve the batch commands. You can know more about it at the wiki: https://github.com/redstone-dart/redstone/wiki/Unit-test

Mock API Requests Xcode 7 Swift Automated UI Testing

Is there a way to mock requests when writing automated UI tests in Swift 2.0. As far as I am aware the UI tests should be independent of other functionality. Is there a way to mock the response from server requests in order to test the behaviour of the UI dependant on the response. For example, if the server is down, the UI tests should still run. Quick example, for login, mock if password failed then UI should show alert, however, if the login is successful the next page should be shown.
In its current implementation, this is not directly possible with UI Testing. The only interface the framework has directly to the code is through it's launch arguments/environment.
You can have the app look for a specific key or value in this context and switch up some functionality. For example, if the MOCK_REQUESTS key is set, inject a MockableHTTPClient instead of the real HTTPClient in your networking layer. I wrote about setting the parameters and NSHipster has an article on how to read them.
While not ideal, it is technically possible to accomplish what you are looking for with some legwork.
Here's a tutorial on stubbing network data for UI Testing I put together. It walks you through all of the steps you need to get this up and running.
If you are worried about the idea of mocks making it into a production environment for any reason, you can consider using a 3rd party solution like Charles Proxy.
Using the map local tool you can route calls from a specific endpoint to a local file on your machine. You can past plain text in your local file containing the response you want it to return. Per your example:
Your login hits endpoint yoursite.com/login
in Charles you using the map local tool you can route the calls hitting that endpoint to a file saved on your computer i.e mappedlocal.txt
mappedlocal.txt contains the following text
HTTP/1.1 404 Failed
When Charles is running and you hit this endpoint your response will come back with a 404 error.
You can also use another option in Charles called "map remote" and build an entire mock server which can handle calls and responses as you wish. This may not be exactly what you are looking for, but its an option that may help others, and its one I use myself.

Alamofire: Handle error globally

I'm trying to handle Alamofire errors globally, similar to this: AFNetworking: Handle error globally and repeat request
One use case would be to detect a 400 status code error (unauthorized / expired API token) and present the login page. Is there a way to hook on something in the Alamofire core or should I create my own error handler and always call validate().response() manually each time?
Thanks
At the moment you will have to handle that logic in your own custom response implementation. We (the Alamofire TC) are currently working on ways that we can make this process easier, but it's very difficult to get right without complicating the rest of the APIs. We're still a ways off yet.
With that said, I built an OAuth 2.0 system that handles this process in a different non-open-source library. It is possible, it's just difficult to do. You will need to hook into the response closure for all requests that could 401. See my answer here for a full breakdown of how to do this.
Hopefully that helps shed some light. Cheers 🍻

iOS REST design pattern advice

I’d like some input on whether there is a better design pattern to use for my iOS app, which uses a REST model to communicate asynchronously with a Django back end.
The server can presently return three types of responses to requests:
a JSON object
a server status code integer
a long Django error message
When an action is performed in the iOS app that requires data from the server, my design pattern looks like this:
An observer is added to notification center, specifying a method that can process the server response
The method puts together and sends a NSURLConnection
A NSURLConnection delegate method receives the response, does some interpretation to check what kind of server response it is, and then posts the appropriate notification to the notification center
This triggers the response method to run, processing the response
My issue with this pattern is that there are a large number of methods written to send and receive individual request and response types. For instance, if I am requesting an item list, I need to add several observers to the notification center, one to process a user list, one to process a blank user list, and one to process errors. Then I need to write custom methods for each one of those three to perform the appropriate actions and remove the observers, based on what kind of response the server sends.
Furthermore, the NSURLConnection delegate ends up being fairly complex, because I’m trying to interpret what type of a response was received (what types of items were in the list received?) without much context of what was requested, to make sure I don’t call the wrong response method when a server message comes back.
I am fairly new to both iOS programming and to REST programming, so I may be missing something obvious. Any advice or links to resources is appreciated.
I'd initially look at using RestKit to abstract your code away from the network comms so you can worry more about the data model and high level requests. Secondly, I wouldn't use notifications for this as it will likely get messy and be very hard to manage multiple simultaneous requests - delegation or block callbacks will be much better for this.
Your REST implementation is mostly server side, and emprirically you'd be passing and receiving binary. There are factors to consider, including whether you are utilizing HTTP.
Working with JSON with NSJSONSerialization class, and NSURLConnection keeps your program more lean and mean.

Resources