Coder Social home page Coder Social logo

bustoutsolutions / siesta Goto Github PK

View Code? Open in Web Editor NEW
2.2K 53.0 159.0 14.53 MB

The civilized way to write REST API clients for iOS / macOS

Home Page: http://siestaframework.com

License: MIT License

Swift 96.64% Objective-C 2.30% Ruby 1.06%
swift ios macos networking rest caching observer reactive

siesta's People

Contributors

acecilia avatar akaralar avatar alex293 avatar axandreo avatar bradhowes avatar brucer42 avatar ejensen avatar hugal31 avatar jlampa avatar jonsteinmetz-adobe avatar karlshea avatar leomehlig avatar lifeisfoo avatar omidontop avatar onekiloparsec avatar paddlefish avatar pcantrell avatar reedyuk avatar snoozemoose avatar tjscalzo avatar vdka avatar victorcotap avatar vvondra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

siesta's Issues

Easy cookies management

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.

Replace Nocilla in specs

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.

Replace ad hoc content type handling in Entity w/MediaType struct

Entity’s handling of media types has several related subtle flaws:

  • Entity returns the content type as an unparsed string, which maybe contain obscure media type options (text/x.vnd.crazy+plain; charset=utf-8; vndparam=whatever) and thus be difficult to work with.
  • Related to the above, the nice media type matching available to ResponseTransformers isn't available anywhere else.
  • The code leans on NSHTTPURLResponse to extract the charset, which means that charset is confusingly a stored property where contentType and etag are derived from headers. This means that (1) contentType and charset can conflict, and (2) charset is an annoying special case in the init & serialization code.

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.

Expose public API for creating Requests with pre-send failure

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?

Adding persistent data store to Siesta

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.

No such module 'Siesta'

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.

Add OS X support

  • Add OS X target
  • Either make iOS-specific code build conditionally or move it to a separate framework
  • Prove viability with a test app
  • Get specs running on OS X
  • Add OS X environment(s) to Travis build matrix

(Looks like @onekiloparsec may be working on this on a fork?)

Removing plist files in a command-line build / Jenkins

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

Deprecation Swift 3

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

Certificate pinning support

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.

Mapping Response as Models

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

ResourceStatusOverlay displays error even when cached data is available

The Problem

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.

Proposed Solution

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...

Allow EntityCache to function at any point in the transformer pipeline

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:

siesta pipeline 1

However, it’s problematic when the transform pipeline produces a model, which can be difficult for an EntityCache to store and retrieve:

siesta pipeline 2

Attempts to solve this problem by keeping models in a database quickly become problematic:

  • The database needs to be able to look up models by REST URL, which mixes abstraction layers and leads to hackish workarounds.
  • The 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:

siesta pipeline 3

…or even:

siesta pipeline 4

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?

Siesta-Swift.h emitted with wrong Objective-C class names

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.)

Support HTTP2?

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…

Configuration not working

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.

Cannot create Siesta.Error.InvalidJSONObject

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 '()'

typedContent not available in Objective C bridge

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?

Unsupported URL error?

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.

Siesta configuration & login server call

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")
}

Debug log

[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"

configureTransformer - Cannot invoke with an argument list

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 :)

Better URL Pattern Matching

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.

Ability to integrate just using source

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.

addObserver with Closure - Type of Expression is ambiguous without more context

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

configureTransformer returns double-optional content

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
    }

Response transformer for JSON with associated objects

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!

Crash when using NetworkDetails for logging

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
)

Help with a session based token REST API

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

RemoteImageView can not load image from aws cloudfront

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?

Attaching response transformers depending on the request rest method (put/post...)

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

Observe a resource and all params variant

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.

Cannot upload to app store

With pod 'Siesta', '>=1.0-beta.6'
building archive is successful and validation is successful but when I try to upload to iTunes connect I am presented with the following:

screen shot 2016-01-17 at 2 43 40 pm

ugh... My workaround was to change my version to something like 0.1.6.

Installation instructions for pod

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"

ERROR ITMS-90060 (CFBundleShortVersionString)

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

Service.addObserver(owner: closure:) Allows multiple observers for self

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.

issue with post

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.

Memory Management review

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

Add tvOS support [partially completed]

  • Add tvOS target
  • Prove viability with a test app
  • Get specs passing on tvOS
  • Add tvOS environment(s) to Travis build matrix
  • Ensure it works with:
    • Carthage
    • CocoaPods

(Looks like @djz-code may be working on this on a fork?)

"Cannot parse server response" with HTTP 204

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?

Manipulate and resend a JSON response

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?

More flexible Resource cache eviction policy

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.

Update API for Apple’s newly released API design guidelines

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.