bustoutsolutions / siesta Goto Github PK
View Code? Open in Web Editor NEWThe civilized way to write REST API clients for iOS / macOS
Home Page: http://siestaframework.com
License: MIT License
The civilized way to write REST API clients for iOS / macOS
Home Page: http://siestaframework.com
License: MIT License
I don't find it easy to add or remove the cookies in the request header.
Is it possible to add a function expressly to manage the cookies?
Or should't the client at least manage the cookies by itself, depending on the response header?
I couldn't login with my application, because the client seems to ignore the "set-cookie" in the server response header, and it fails to send the cookies back in the following requests.
Nocilla has internal race conditions, and appears to be ill-maintained or abandoned. It works well enough for now, but it’s not ideal. Let’s investigate another HTTP stubbing framework.
@onekiloparsec points out the venerable OHHTTPStubs. Would need to investigate whether it can do ad hoc stubbing in code instead of reading from files.
Mockingjay looks interesting.
The ability to explicitly delay and then resume responses is essential for Siesta’s specs. Any alternative would need to have that.
Entity
’s handling of media types has several related subtle flaws:
text/x.vnd.crazy+plain; charset=utf-8; vndparam=whatever
) and thus be difficult to work with.A nice solution to all these things would be to expose a robust MediaType struct instead of a raw string. Something to do after all the basics are in place.
I am using JSONCore which provides a more native swift experience for working with JSON and have configured transformers no problem, however the request(_: RequestMethod, json: NSJSONConvertible) -> Request
method is incompatible with the way JSONCore stores parsed JSON. I thought, no issue, I will extend Resource to add my a method with the signature request(_: RequestMethod, json: JSON) -> Request
and follow the Siesta implementation. The issue I have run into is I cannot return a FailedRequest
since it is internal. This is the only thing stopping me implementing this, is there a reason for this to be marked internal
?
I'm looking at using Siesta in an app where one of the major use cases is that the user can download content for offline use, and otherwise have a decent experience in the app offline or with a dodgy network. I have a dream for this app!
In my dream, the model layer would be oblivious to network conditions and would receive either live data or stored data (with live updates, if they become available). Would it make sense to add some kind of support for a persistent data store in Siesta, or is that better handled in a wrapper around Siesta? I'm in my initial design phase; any pointers you can give me would be appreciated.
I've just installed Siesta (1.0-beta.4) using cocoapods, but when I try to import it with import Siesta
inside a swift file I receive this error.
This is my Podfile:
platform :ios, '8.0'
use_frameworks!
pod 'Siesta', '~>1.0-beta.4'
I'm using xcode 7.2.
Thank you.
(Looks like @onekiloparsec may be working on this on a fork?)
Hello,
I'm currently using Siesta framework in an internal iOS framework (written in Swift). This framework is built and tested by our Jenkins server. Sometimes, Jenkins may have some trouble cleaning the Build folder.
I use the XCode plugin for Jenkins, it build then test the project. It seems to build it two times in a row (one for the default action "build" and another for my custom settings that tells him to "test" the project).
After the second step, my build fails (each time - i do a manual xcodebuild clean before running into XCode plugin). Here is my output :
Testing failed:
Failed to remove /Users/jenkins/Library/Developer/Xcode/DerivedData/AXCoreSwift-cejrqtokifrbcyaxysroapbfuahi/Build/Products/Release-iphoneos/Siesta/Siesta.framework/Info-iOS.plist: “Info-iOS.plist” couldn’t be removed.
Failed to remove /Users/jenkins/Library/Developer/Xcode/DerivedData/AXCoreSwift-cejrqtokifrbcyaxysroapbfuahi/Build/Products/Release-iphoneos/Siesta/Siesta.framework/Info-OSX.plist: “Info-OSX.plist” couldn’t be removed.
Command /bin/sh emitted errors but did not return a nonzero exit code to indicate failure
Linker command failed with exit code 1 (use -v to see invocation)
** TEST FAILED **
It might be caused by permissions issues or a mistake while setting up my Jenkins, but i also managed (rarely, so very difficult to reproduce) to get it while building from XCode.
FYI, i also use SwiftyJSON and a few UI pods, nothing about another networking library.
I can provide as much informations as needed
What is the recommended approach for displaying multiple pages of results using Siesta? I wasn't able to find any relevant documentation or examples, please let me know if I've missed something. Thanks!
Is there any further API examples? Would be great to see how this could be implemented with a token based authentication system.
I used Carthage to build Siesta and the complier got me the following warnings.
Checkouts/siesta/Source/Support/GCD+Siesta.swift:22:59: warning: FUNCTION is deprecated and will be removed in Swift 3, please use #function
Carthage/Checkouts/siesta/Source/Support/Collection+Siesta.swift:83:29: warning: passing 2 arguments to a callee as a single tuple value is deprecated
A common way to add ssl pinning support in iOS apps is to use the NSURLConnectionDelegate
to define a custom didReceiveAuthenticationChallenge
. How to add this security feature to Siesta framework?
For a complete example see the OWASP website.
How to configure transformer for the service with models
service().configureTransformer("/data/2.5/forecast/city?id=524901&APPID=fbb20b6f256459684791c9be06a8ce20") {
($0.content as JSON).arrayValue.map(ObjectModel.init)
}
I tried something like this but it gives cannot parse server response expected JSON but actual dictionary
We have multiple observers for the same resource because we are polling for updates on a timer in the background for the same data that UIViewControllers are observing. If the background update process attempts to get fresh data and is unable to while a ViewController also observing the resource (and is visible to the user), when that ViewController receives a ResourceChanged callback, the ResourceStatusOverlay view displays the error even though we have a cached (albeit stale) version of that resource's data. This does not seem correct. It seems like we should show the stale, cached data.
A simple change on line 121 of ResourceStatusOverlay.swift from:
else if let error = res.latestError
to:
else if let error = res.latestError where resource.latestData == nil
seems to do the trick.
I'm happy to submit a pull request if that's easier...
EntityCache currently must store and return only the values at the very end of the transformer pipeline.
This works well when the end result of the pipeline is an easily serializable type such as text or JSON:
However, it’s problematic when the transform pipeline produces a model, which can be difficult for an EntityCache
to store and retrieve:
Attempts to solve this problem by keeping models in a database quickly become problematic:
EntityCache
API is not designed to work with databases. (For example, it wants to pass cached entities across threads, which Realm doesn’t like.)Suppose, however, that an EntityCache
could insert itself at any point in the transformer pipeline and not just the end. In other words, this is currently the only supported structure:
→ JSON transformer → Model transformer → (EntityCache) →
…but suppose the pipeline instead supported this:
→ JSON transformer → (EntityCache) → Model transformer →
When there is a cache hit, the pipeline would pick up immediately after the cache's position in the pipeline. An EntityCache
could then work only with its preferred data type:
…or even:
This would require some hard thought in the plumbing, but seems to make sense. @annicaburns, would this solve the problems you were having with EntityCache
? Would you still want to use Realm even with a mechanism like this in place?
Apparently due to an Apple bug, Xcode emits this:
SWIFT_CLASS("BOSService")
@interface Service : NSObject
…where it should emit this:
SWIFT_CLASS("Service")
@interface BOSService : NSObject
This exposes Siesta types to Objective-C without the BOS prefix. (Methods are mapped correctly; the bug only affects classes & protocols.)
Debug info:
[Siesta:Network] GET https://domain.com/v1/feeds
[Siesta:Network] – ← GET https://domain.com/v1/feeds
[Siesta:StateChanges] Siesta.Resource(https://domain.com/v1/feeds)[] received error: Error(userMessage: "The operation couldn’t be completed. Protocol error", httpStatusCode: nil, entity: nil, cause: Optional(Error Domain=NSPOSIXErrorDomain Code=100 "Protocol error" UserInfo={NSErrorPeerAddressKey=<CFData 0x7fd040c43980 [0x103aeb7b0]>{length = 16, capacity = 16, bytes = 0x100201bb77…
Do you have support for Rx, or I misunderstand the observer logic?
Alamofire is an optional dependency, but getting weird errors from example project when I remove it. Investigate.
I am attempting to set custom headers for all requests made using Siesta.
In a Service subclass, I do the following:
init() {
super.init(baseURL: "http://192.168.1.90:5000/api")
configure {
$0.config.headers["X-TEST"] = "lol"
}
}
Yet the X-TEST header never gets sent to the server.
I am attempting throw an error on all "text/*" responses.
I copied the 'TextResponseTransformer' func into my own class in attempt to reduce it to...
public func TextResponseTransformer(transformErrors: Bool = true) -> ResponseTransformer
{
return ResponseContentTransformer(transformErrors: transformErrors)
{
(content: NSData, entity: Entity) throws -> String in
let error = Siesta.Error(userMessage: "Response transformation failed.", cause: Error.Cause.InvalidJSONObject())
}
}
Xcode7.2 is giving me this error 'Cannot invoke value of type 'Error.Cause.InvalidJSONObject.Type' with argument list '()'
Hello,
Can you please tell if it is possible to access transformed content from an Objective C code? I understand that this functionality was probably not bridged to Objective C due the lack of generics in it. But the ability to map resources to model objects would be so useful that I think, creating untyped version of "typedContent" specifically for bridging to Objective C would worth it. Am I misunderstanding the point?
Over at SO I have posted a question about siesta erroring-out on a simple post request:
http://stackoverflow.com/questions/33147850/siesta-ios-post-request-errors-out-with-unsupported-url
Unfortunately I cannot create a new "siesta-swift" since I haven't got enough reputation to create a new tag.
let api = Service(base: "http://myapidomain.net/rest")
enabledLogCategories = LogCategory.all
let parameters = ["username": "username", "password": "password"]
api.resource(url: "users/login").request(.POST, json: NSDictionary(dictionary: parameters)).success { data in
debugPrint("success logging in")
}.failure { error in
debugPrint("failed to log in")
}
[Siesta:Configuration] Computing configuration for Siesta.Resource(users/login)[]
[Siesta:Configuration] Applying config 0 [Siesta default response transformers] to Siesta.Resource(users/login)[]
[Siesta:NetworkDetails] Request:
headers: (1)
Content-Type: application/json
[Siesta:Network] POST users/login
[Siesta:Network] – ← POST users/login
[Siesta:NetworkDetails] Raw response headers: –
[Siesta:NetworkDetails] Raw response body: 0 bytes
[Siesta:NetworkDetails] Response after transformer pipeline: (new data)
Failure
userMessage: "unsupported URL"
nsError: "unsupported URL"
"failed to log in"
When trying to use configureTransformer as follows:
configureTransformer("/foo") { String($0) }
I get the following error:
Cannot invoke 'configureTransformer' with an argument list of type '(String, (_) -> _)'
From the documentation in the code, this seems like it should work. However, I'm not enough of a Swift expert to figure out what exactly that chunk of code is expecting :)
I have setup a handful of routes such as:
api.configureTransformer("/products/filters") { returns Filter }
api.configureTransformer("/products/*") { returns Product }
api.configureTransformer("/products/*/market") { returns Market }
When the '/products/filters' resource is loaded it handles it then passes 'Filter' objects into the 'products/*' handler which expects a JSON (SwiftyJSON) object. So of course the 'WrongTypeInTranformerPipeline' error pops up.
It would be nice to either allow a ResponseTransformer to say "no more transforming, we are done" or allow for better pattern matching in the URLs such as specifying the wildcard item should be an INT.
I settled on using Carthage but I would rather use git submodules and include the source myself. Any thoughts on supporting this workflow? When I last tried that there was one place that did an import Siesta
which is not compatible with including source from what I can tell.
I have done a clean and a clean build directory which does not help.If I add
github "Alamofire/Alamofire" "3.1.2"
to my Cartfile then things seem to build and run. Is this as intended?
Thanks
I'm working on a Proof-of-Concept using Siesta, and am fairly new to Swift coming from Objective-C so please forgive if this is a basic question.
I'm following the model Transform example in the README, trying to use a the model object with typedContent() in my closure, but i keep seeing the "ambiguous without more context error"
here is the closure in viewDidLoad()
API.resource("/profile/").addObserver(self) {
[weak self] in
self?.refreshText($0.typedContent()) //"Type of expression is ambiguous without more context"
}
and refreshText is simple
func refreshText(user: MiniUser){
self.txtView.text = user.fullName
}
this seems like it should work in a straightforward way, any ideas on what might be wrong with this? it seems to work if i make the ViewController a ResourceObserver and use the delegate call instead, but the closure has been problematic. edited: this does not work either, it gives a similar "ambiguous" error
Checking to see if there are any examples or tips on using ObjectMapper for model mapping in Siesta.
I think something as simple as this should work, where User is a working ObjectMapper Mappable model, and I'm using the SwiftyJSON global transformer from @pcantrell here.
configureTransformer("/profile/") {
Mapper<User>.map($0.content as JSON) //error: type of expression is ambiguous without more context
}
Hi,
First of all, nice work on this library!
From what I read/tried about how JSON responses are parsed, I could see that the way to do it is something like:
JSON (notice that all cars
have the same user
):
{
"cars": [
{
"model": "Ford",
"user": {
"username": "exampleuser",
"email": "[email protected]"
}
},
{
"model": "Chevrolet",
"user": {
"username": "exampleuser",
"email": "[email protected]"
}
},
{
"model": "Renault",
"user": {
"username": "exampleuser",
"email": "[email protected]"
}
}
]
}
Models:
import SwiftyJSON
class Car {
var model: String!
var user: User!
init(json: JSON) {
self.model = json["model"].string
self.user = User(json: json["user"])
}
}
class User {
var username: String!
var email: String!
init(json: JSON) {
self.username = json["username"].string
self.email = json["email"].string
}
}
Transformer:
service.configureTransformer("/cars") {
($0.content as JSON).arrayValue.map(Car.init)
}
However, turns out that our APIs often respond with JSONs formatted in a different way: that is, having associated objects instead of nested ones, so shared objects are not included more than once. For example, the one above would look like this, with only one user
object in the response:
{
"cars": [
{
"model": "Ford",
"user_id": "1"
},
{
"model": "Chevrolet",
"user_id": "1"
},
{
"model": "Renault",
"user_id": "1"
}
],
"users": [
{
"id": "1",
"username": "exampleuser",
"email": "[email protected]"
}
]
}
Is there any way to configure a transformer to handle this responses in a neat way?
Thanks!
I am using my own JSON library and suspect the logging code is trying to apply Siesta's default JSON transformer after having already applied my own.
This is part of my configuration code so the default transformers should be cleared:
service.invalidateConfiguration()
service.configure {
$0.config.responseTransformers.clear()
$0.config.responseTransformers.add(VDKAJSONResponseTransformer(), contentTypes: ["application/json"])
}
Crashes on this line with the following message:
2016-05-12 13:37:27.309 Example[13126:14501541] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (RLMStandalone_Business)'
*** First throw call stack:
(
0 CoreFoundation 0x00000001095fed85 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010b3a2deb objc_exception_throw + 48
2 CoreFoundation 0x00000001095fecbd +[NSException raise:format:] + 205
3 Foundation 0x0000000109af3d37 _writeJSONValue + 698
4 Foundation 0x0000000109af7b55 ___writeJSONArray_block_invoke + 132
5 CoreFoundation 0x000000010954f374 __NSArrayEnumerate + 596
6 Foundation 0x0000000109af738d _writeJSONArray + 330
7 Foundation 0x0000000109af3ca5 _writeJSONValue + 552
8 Foundation 0x0000000109af3a29 -[_NSJSONWriter dataWithRootObject:options:error:] + 124
9 Foundation 0x0000000109af644a +[NSJSONSerialization dataWithJSONObject:options:error:] + 333
10 Siesta 0x00000001090452a3 _TTSf4s_n___TFV6Siesta6Entity4dumpfTSS_SS + 3779
11 Siesta 0x0000000109043277 _TFO6Siesta8Response4dumpfTSS_SS + 871
12 Siesta 0x000000010906fe18 _TFFC6Siesta14NetworkRequestP33_F4119EBBA687DD6620E1C88F0CE6640517broadcastResponseFT8responseOS_8Response5isNewSb_T_u_KT_GSaGSqP___ + 280
13 Siesta 0x00000001090523c9 _TF6Siesta8debugLogFTOS_11LogCategoryKT_GSaGSqP____T_ + 297
14 Siesta 0x000000010906ba8a _TPA__TFC6Siesta14NetworkRequestP33_F4119EBBA687DD6620E1C88F0CE6640517broadcastResponsefT8responseOS_8Response5isNewSb_T_ + 4826
15 Siesta 0x000000010906fcd8 _TFFFC6Siesta14NetworkRequestP33_F4119EBBA687DD6620E1C88F0CE6640517transformResponseFTT8responseOS_8Response5isNewSb_4thenFT8responseS1_5isNewSb_T__T_U_FT_T_U_FT_T_ + 568
16 libdispatch.dylib 0x000000010cb99d9d _dispatch_call_block_and_release + 12
17 libdispatch.dylib 0x000000010cbba3eb _dispatch_client_callout + 8
18 libdispatch.dylib 0x000000010cba21ef _dispatch_main_queue_callback_4CF + 1738
19 CoreFoundation 0x00000001095580f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
20 CoreFoundation 0x0000000109519b99 __CFRunLoopRun + 2073
21 CoreFoundation 0x00000001095190f8 CFRunLoopRunSpecific + 488
22 GraphicsServices 0x000000010dc94ad2 GSEventRunModal + 161
23 UIKit 0x0000000109e26f09 UIApplicationMain + 171
24 Example 0x0000000108b1c4c2 main + 114
25 libdyld.dylib 0x000000010cbee92d start + 1
26 ??? 0x0000000000000001 0x0 + 1
)
Using form-data
Hey there,
The API web service that I've got uses a session based token which expires every 24h. This means I have to make a new call to (let's say) the /authenticate_session endpoint and obtain a new session token. Now I have to take the response from this and pass it for every subsequent API call for other endpoints.
That's all nice and simple to implement using your basicAuthToken example.
My problem is, how can I check the error response and retry the call automatically? For example, let's say I make a GET request for the /user endpoint with an expired JSON web token. Here's the error response I get:
entity: Optional(Siesta.Entity(content: [success: 0, error: {
code = E1100;
hint = Token;
message = "Session token has expired.";
}]
What I'd like to do is whenever I get an error with the above code (E1100), I'd like it to call the /authenticate_session endpoint, use the new token that gets returned and automatically make another GET /user request. I don't want the initial GET /user request to fail, instead I want it to try and handle/recover from it. If it then fails, I want to update the UI etc.
Is this possible with Siesta right now or do I need to manually handle this (manually as in inside my resourceChanged delegate function, I manually check what the error is and handle it there for every endpoint the API supports)? Can I instead somehow handle this using the responseTransformer for the Service object?
Any help in the right direction would be appreciated.
Thanks
Thank you for great library, i love siesta so much.
Today i cutch interesting issue with RemoteImageView, i am not clear is it problem of response from my aws cloudfront settings, or the extension.
This is what is go on.
This works fine:
self.demoImage.imageURL = "http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg"
But this do not display image
self.demoImage.imageURL = "https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg"
I check same urls with AlamofireImage library and both images are displayed, but Siesta's image extension does not.
My current configuration is pod 'Siesta/Alamofire', '>=1.0-beta.6'
Debug log looks interesting
this is for image which is displayed
cachesPath: /var/mobile/Containers/Data/Application/AFCA65BD-5E5C-40B1-98FE-06A283C4DECE/Library/Caches
[Siesta:Configuration] Computing configuration for Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[]
[Siesta:Configuration] Applying config 0 [Siesta default response transformers] to Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[]
[Siesta:Staleness] Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[] is not up to date: no error | no data
[Siesta:Network] GET http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg
[Siesta:Observers] Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[L] sending Requested to 0 observers
[Siesta:Network] 200 ← GET http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg
[Siesta:ResponseProcessing] ResponseContentTransformer<NSData, UIImage>(processor: (Function), skipWhenEntityMatchesOutputType: true, transformErrors: false) matches content type "image/jpeg"
[Siesta:StateChanges] Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[] received new data from Network : Entity(content: <UIImage: 0x155ba860>, {1800, 1200}, charset: nil, headers: ["date": "Sun, 03 Apr 2016 13:23:34 GMT", "accept-ranges": "bytes", "server": "Microsoft-IIS/5.0", "last-modified": "Tue, 07 Apr 2015 02:34:49 GMT", "content-type": "image/jpeg", "etag": "\"e693396bdb70d01:8b8\"", "content-l…
[Siesta:Observers] Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[D] sending NewData(Network) to 1 observer
[Siesta:Observers] Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[D] sending NewData(Network) to (ClosureObserver in _C44BB9FA2CCB62875EDCC4C65C6D80F6)(closure: (Function))
This is for AWS CloudFront
cachesPath: /var/mobile/Containers/Data/Application/1B4EC435-C915-46FE-AB66-05D76FC79810/Library/Caches
[Siesta:Configuration] Computing configuration for Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[]
[Siesta:Configuration] Applying config 0 [Siesta default response transformers] to Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[]
[Siesta:Staleness] Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[] is not up to date: no error | no data
[Siesta:Network] GET https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg
[Siesta:Observers] Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[L] sending Requested to 0 observers
[Siesta:Network] 200 ← GET https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg
[Siesta:StateChanges] Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[] received new data from Network : Entity(content: <OS_dispatch_data: data[0x1564b580] = { composite, size = 231103, num_records = 11 record[0] = { from = 0, length = 16384, data_object = 0x15649a00 }, record[1] = { from = 0, length = 16384, data_object = 0x15557f80 }, record[2] = { from = 0, length = 16384, data_object = 0x156499b0 …
[Siesta:Observers] Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[D] sending NewData(Network) to 1 observer
[Siesta:Observers] Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[D] sending NewData(Network) to (ClosureObserver in _C44BB9FA2CCB62875EDCC4C65C6D80F6)(closure: (Function))
For me, noticeable difference in Entity(content: <UIImage
and Entity(content: <OS_dispatch_data: data
is interesting part. But my knowledge in cocoa is as deep.
Maybe this is incorrect settings in my CloudFront configuration, but in reason AlamofireImage extension get it right.
What do you think?
I store my base URL as a NSURL
, and every time I call the Service
initializer (which isn't often, but I keep moving it), I have to cast it to a String
. Its a tiny quibble, but since its so easy to fix, I thought I'd mention it.
Keep up the great work Paul!
Hello,
First of all, thanks for making this library which simplifies a lot of my work.
I was wondering if there was a way to attach a specific transformer to a route but only if the request method if POST/PUT/DEL/GET. Currently, my API is designed so that only the method differs, not the url, and quite a few apis are like this.
Is there an easy way to attach a transformer depeding on the rest method?
Best regards,
Gilles Major
I've a tableview for a list of objects that are returned from an url like /resource
.
In the same view there is a filter to get only a part of these object using a url like /resource?filterByDate=2015-12-18
.
In the Siesta withParam
documentation there is a statement about the uniqueness of the Resource given from its full URL.
In this way I need to add an observer (the view, self
), to a new Resource, every time the user select a different filter for the list.
Is there a way to observe a resource and, automatically, all its "withParams" variants? Something like myResource.observeAllParams(self)
.
I've seen the source but I didn't find an easy way to implement this.
Swift framework classes with an @objc(Name)
annotation are not usable under either the Swift name or the Obj-C name within a storyboard.
The current workaround is to define a dummy subclass in the project using Siesta:
class ResourceStatusOverlay: Siesta.ResourceStatusOverlay { }
The storyboard can now see that class.
This is a minor point that will fix itself when 1.0 is finally released but currently pod install emits an error if you type in example what is on the read me.
To make it work you need
pod "Siesta", ">=1.0-beta.4"
Trying to upload the ipa to the app store I receive this error:
ERROR ITMS-90060: "This bundle is invalid. The value for key CFBundleShortVersionString '1.0-beta.4' in the Info.plist file must be a period-separated list of at most three non-negative integers."
Seems to be a very common problem, since from some time Apple is enforcing a three non-negative integers version number even for modules/frameworks.
There is also a dedicated document from Apple about version and build numbers
I was doing some testing of grabbing a resource, adding an observer and calling load in viewDidAppear. Within the closure I would print the 'event' and noticed after multiple calls to viewDidAppear the print statement was being called multiple times per an event.
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
MyAPI.resource('/home').addObserver(owner: self, closure: {
[weak self] resource, event in
print(event)
}
}
I dug around a bit and it appears that it might just be an issue with the ClosureObserver.
Greetings,
The siesta framework code below does not work, but the Alamofire code does work. My server sends back a 400 for the request sent by siesta. I would expect these to do the same thing, but perhaps I am missing something:
HighlightAPI.sync().request(.POST, json: dictionary as! NSDictionary)
Alamofire.request(.POST, "http://localhost:8080/api/private-highlights/sync", parameters: dictionary, encoding: .JSON)
where HighlightAPI.sync() returns the same url as in the Alamofire call.
Swift’s open sourcing has revealed interesting details about how weak references work internally:
https://www.mikeash.com/pyblog/friday-qa-2015-12-11-swift-weak-references.html
The section of note:
Weak references to an object will cause that object's memory to remain allocated even after there are no strong references to it, until all weak references are either loaded or discarded. This temporarily increases memory usage. Note that the effect is small, because while the target object's memory remains allocated, it's only the memory for the instance itself. All external resources (including storage for Array or Dictionary properties) are freed when the last strong reference goes away. A weak reference can cause a single instance to stay allocated, but not a whole tree of objects.
Review Siesta’s memory management policies in light of this. Relevant sections of code:
https://github.com/bustoutsolutions/siesta/blob/master/Source/Support/ARC%2BSiesta.swift
https://github.com/bustoutsolutions/siesta/blob/master/Source/Support/WeakCache.swift#L51-L52
https://github.com/bustoutsolutions/siesta/blob/master/Source/ResourceObserver.swift#L297-L303
(Looks like @djz-code may be working on this on a fork?)
If I understand the Siesta documentation correctly, when doing a POST request, it should be acceptable to receive HTTP 204 with no body. When I attempt that, I get the following:
[Siesta:Network] POST http://localhost/account
[Siesta:Network] 204 ← POST http://localhost/account
[Siesta:NetworkDetails] Raw response headers: [Content-Length: 0, Access-Control-Allow-Origin: *, Vary: Accept, Content-Type: application/json; charset=utf-8, Content-Language: en-US, Access-Control-Allow-Headers: *, Connection: Keep-Alive, Access-Control-Max-Age: 1000, Expires: 0, Server: Apache/2.4.7 …
[Siesta:NetworkDetails] Raw response body: 0 bytes
[Siesta:ResponseProcessing] ResponseContentTransformer<NSData, NSJSONConvertible>(processor: (Function), skipWhenEntityMatchesOutputType: true, transformErrors: true) matches content type "application/json; charset=utf-8"
[Siesta:ResponseProcessing] ResponseContentTransformer<NSData, NSJSONConvertible>(processor: (Function), skipWhenEntityMatchesOutputType: true, transformErrors: true) → Error(userMessage: "Cannot parse server response", httpStatusCode: nil, entity: nil, cause: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}), timestamp: 469262441.985034)
[Siesta:NetworkDetails] Response after transformer pipeline: (new data)
Failure
userMessage: "Cannot parse server response"
cause: Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}
Is there something I need to do in order to get this to work?
I'm using siesta with SwiftyJSON, and I've a login call that returns some json data that I need to resend after a proper manipulation:
//api.login is a Resource
api.login.request(.POST, json: [:])
.success() { response in
var res = response.json
//example manipulation
res["cbs"][0]["input"][0]["value"].string = "00000"
api.login.request(.POST, json: res).success(){/*...*/}
}
But this code generate a static error:
Argument type 'JSON' does not conform to expected type 'NSJSONConvertible'
Howto manipulate response data between two (ore more) request?
Resources are currently eligible for deallocation on a low memory event. This works fine in most iOS apps, but (1) will not work on desktop apps, where low memory events do not exist, and (2) may cause memory churn for apps cycling rapidly through many resources.
WeakCache
should support a more flexible eviction policy — perhaps akin to NSCache
, perhaps more rule-based and resource-aware.
I reviewed Siesta’s API against Apple’s new API Design Guidelines for Swift, and identified ~27 names of concern. Of those, I recommend changing 8 14.
Details of my review, proposed changes, and rationale are in this gist: https://gist.github.com/pcantrell/22a6564ca7d22789315b
If anybody has opinions about these changes, or notices other places where Siesta’s naming conventions contradict the new guidelines, please comment on this issue.
API changes will appear as deprecations in beta 6, and the deprecated methods will be removed in the subsequent release.
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.