Elegantly connect to a JSON api. (Alamofire + Promises + JSON Parsing)

Overview

ws

Important Notice: Farewell ws... hello Networking !

Networking is the next generation of the ws project. Think of it as ws 2.0 built for iOS13. It uses Combine native Apple's framework over Then Promise Library, removes Arrow dependency to favour Codable (Arrow can still be adapted easily though) and removes the Alamofire dependency in favour of a simpler purely native URLSession implementation. In essence, less dependencies and more native stuff with an almost identical api. If your app supports iOS13 and up, it is strongly advised to migrate to Networking. WS will be "maintained" for backwards compatibility reasons but consider it deprected starting iOS13.

ws

Language: Swift 5 Platform: iOS 8+ Carthage compatible Cocoapods compatible License: MIT Build Status codebeat badge Release version

Reason - Example - Installation

let ws = WS("http://jsonplaceholder.typicode.com")

ws.get("/users").then { json in
    // Get back some json \o/
}

Because JSON apis are used in 99% of iOS Apps, this should be simple.
We developers should focus on our app logic rather than boilerplate code .
Less code is better code

Try it!

ws is part of freshOS iOS toolset. Try it in an example App ! Download Starter Project

How

By providing a lightweight client that automates boilerplate code everyone has to write.
By exposing a delightfully simple api to get the job done simply, clearly, quickly.
Getting swift models from a JSON api is now a problem of the past

What

  • Build concise Apis
  • Automatically maps your models
  • Built-in network logger
  • Stands on the shoulder of giants (Alamofire & Promises)
  • Pure Swift, Simple & Lightweight

Usage

Bare JSON

import ws // Import ws at the top of your file
import Arrow // Import Arrow to get access to the JSON type

class ViewController: UIViewController {

    // Set webservice base URL
    let ws = WS("http://jsonplaceholder.typicode.com")

    override func viewDidLoad() {
        super.viewDidLoad()

       // Get back some json instantly \o/
       ws.get("/users").then { (json:JSON) in
           print(json)
       }
    }
}

Set up Model parsing

Create a User+JSON.swift file and map the JSON keys to your model properties

import Arrow

extension User: ArrowParsable {

    mutating func deserialize(_ json: JSON) {
        identifier <-- json["id"]
        username <-- json["username"]
        email <-- json["email"]
    }
}

Note: ws uses Arrow for JSON Parsing https://github.com/freshOS/Arrow

Choose what you want back

Here you are going to create a function that wraps your request. There are different ways of writing that function depending on what you want back. An empty block, the JSON, the model or the array of models.

Promise { return ws.get("/users") } func singleModelCall() -> Promise { return ws.get("/users/3") } func modelArrayCall() -> Promise<[User]> { return ws.get("/users") } ">
func voidCall() -> Promise<Void> {
    return ws.get("/users")
}

func jsonCall() -> Promise
      {
    
     return ws.
     get(
     "/users")
}


     func 
     singleModelCall() 
     -> Promise
     
       {
    
      return ws.
      get(
      "/users/3")
}


      func 
      modelArrayCall() 
      -> Promise<[User]> {
    
      return ws.
      get(
      "/users")
}
     
    

As you can notice, only by changing the return type, ws automatically knows what to do, for instance, try to parse the response into User models.

This enables us to stay concise without having to write extra code. \o/

Note: ws uses then for Promises https://github.com/freshOS/then

Get it!

voidCall().then {
    print("done")
}

jsonCall().then { json in
    print(json)
}

singleModelCall().then { user in
    print(user) // Strongly typed User \o/
}

modelArrayCall().then { users in
    print(users) // Strongly typed [User] \o/
}

Settings

Want to log all network calls and responses?

ws.logLevels = .debug

Want to hide network activity indicator?

ws.showsNetworkActivityIndicator = false

Want to override the default session manager to customize trust policies?

import Alamofire

ws.sessionManager = SessionManager(serverTrustPolicyManager: ServerTrustPolicyManager(
  policies: ["myspecialhostname.com" : .disableEvaluation]
))

Api Example

Here is a Typical CRUD example for Articles :

Promise
{ return ws.post("/articles", params: ["name":name]) } func fetch() -> Promise
{ return ws.get("/articles/\(id)") } func update() -> Promise { return ws.put("/articles/\(id)", params: ["name":name]) } func delete() -> Promise { return ws.delete("/articles/\(id)") } } ">
extension Article {

    static func list() -> Promise<[Article]> {
        return ws.get("/articles")
    }

    func save() -> Promise
      
{ return ws.post("/articles", params: ["name":name]) } func fetch() -> Promise
{ return ws.get("/articles/\(id)") } func update() -> Promise<Void> { return ws.put("/articles/\(id)", params: ["name":name]) } func delete() -> Promise<Void> { return ws.delete("/articles/\(id)") } }

Here is how we use it in code :

// List Articles
Article.list().then { articles in

}

// Create Article
var newArticle = Article(name:"Cool story")
newArticle.save().then { createdArticle in

}

// Fetch Article
var existingArticle = Article(id:42)
existingArticle.fetch().then { fetchedArticle in

}

// Edit Article
existingArticle.name = "My new name"
existingArticle.update().then {

}

// Delete Article
existingArticle.delete().then {

}

HTTP Status code

When a request fails, we often want to know the reason thanks to the HTTP status code. Here is how to get it :

ws.get("/users").then {
    // Do something
}.onError { e in
    if let wsError = e as? WSError {
        print(wsError.status)
        print(wsError.status.rawValue) // RawValue for Int status
    }
}

You can find the full WSError enum here -> https://github.com/freshOS/ws/blob/master/ws/WSError.swift

Bonus - Load More pattern

Very often we deal we lists and the ability to load more items. Here we are going to see an example implementation of this pattern using ws. This is not included because the logic itself depends on your backend implementation. This will give you an example for you to roll out your own version.

Implementation

[T] { let mapper = WSModelJSONParser () let models = mapper.toModels(json) if models.count < limit { canLoadMore = false } return models } } ">
import ws
import then
import Arrow


class LoadMoreRequest<T:ArrowParsable> {

    var limit = 12

    private var params = [String:Any]()
    private var offset = 0
    private var call: WSRequest!
    private var canLoadMore = true
    private var aCallback:((_ ts: [T]) -> [T])? = nil

    init(_ aCall: WSRequest) {
        call = aCall
    }

    func resetOffset() {
        offset = 0
        canLoadMore = true
    }

    func hasMoreItemsToload() -> Bool {
        return canLoadMore
    }

    func fetchNext() -> Promise<[T]> {
        params = call.params
        params["limit"] = limit
        params["offset"] = offset
        call.params = params
        offset += limit
        return call.fetch()
                .registerThen(parseModels)
                .resolveOnMainThread()
    }

    private func parseModels(_ json: JSON) -> [T] {
        let mapper = WSModelJSONParser<T>()
        let models = mapper.toModels(json)
        if models.count < limit {
            canLoadMore = false
        }
        return models
    }
}

As you can see, we have a strongly typed request.
The limit is adjustable.
It encapsulates a WSRequest.
It handles the offset logic and also wether or not there are more items to load.

And that's all we need!

Now, this is how we build a LoadMoreRequest

func loadMoreUsersRequest() -> LoadMoreRequest
    {
    
   return 
   LoadMoreRequest(ws.
   getRequest(
   "/users"))
}
  

Usage

And here is how we use it in our controllers :

class ViewController: UIViewController {

    // Get a request
    let request = api.loadMoreUsersRequest()

    override func viewDidLoad() {
        super.viewDidLoad()
        request.limit = 5 // Set a limit if needed
    }

    func refresh() {
      // Resets the request, usually plugged with
      // the pull to refresh feature of a tableview
      request.resetOffset()
    }

    func loadMore() {
      // Get the next round of users
      request.fetchNext().then { users in
          print(users)
      }
    }

    func shouldDisplayLoadMoreSpinner() -> Bool {
      // This asks the requests if there are more items to come
      // This is useful to know if we show the "load more" spinner
      return request.hasMoreItemsToload()
    }
}

Here you go you now have a simple way to deal with load more requests in your App 🎉

Bonus - Simplifying restful routes usage

When working with a RESTFUL api, we can have fun and go a little further.

By introducing a RestResource protocol

public protocol RestResource {
    static func restName() -> String
    func restId() -> String
}

We can have a function that builds our REST URL

public func restURL<T:RestResource>(_ r:T) -> String {
    return "/\(T.restName())/\(r.restId())"
}

We conform our User Model to the protocol

String { return "\(identifier)" } } ">
extension User:RestResource {
    static func restName() -> String { return "users" }
    func restId() -> String { return "\(identifier)" }
}

And we can implement a version of get that takes our a RestResource

public func get<T:ArrowParsable & RestResource>(_ restResource:T, params:[String:Any] = [String:Any]()) -> Promise
    {               
    
   return 
   get(
   restURL(restResource), 
   params: params)
}
  

then

ws.get("/users/\(user.identifier)")

Can be written like :

ws.get(user)

Of course, the same logic can be applied to the all the other ws functions (post, put delete etc) ! 🎉

Installation

Swift Package Manager (SPM)

Due to the challenge of supporting all package manager at once, SPM support is availlable on a separate branch spm-only.

Carthage

In your Cartfile

github "freshOS/ws"
  • Run carthage update
  • Drag and drop ws.framework from Carthage/Build/iOS to Linked Frameworks and Libraries (“General” settings tab)
  • Go to Project > Target > Build Phases + New run Script Phase

/usr/local/bin/carthage copy-frameworks

Add input files

$(SRCROOT)/Carthage/Build/iOS/ws.framework
$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
$(SRCROOT)/Carthage/Build/iOS/Arrow.framework
$(SRCROOT)/Carthage/Build/iOS/then.framework

This links ws and its dependencies.

Manually

Carthage is pretty useful since it takes care of pulling dependencies such as Arrow, then and Alamofire. What's cool is that it really is transparent. What I mean is that you could just use carthage on the side to pull and build dependencies and manually link frameworks to your Xcode project.

Without Carthage, I'd see 2 solutions : 1 - Copy paste all the source code : ws / then / Arrow / Alamofire which doesn't sound like a lot of fun ;) 2 - Manually link the frameworks (ws + dependencies) by A grabbing .frameworks them on each repo, or B use Carthage to build them

Cocoapods

target 'MyApp'
pod 'ws'
use_frameworks!

Swift Version

Swift 2 -> version 1.3.0
Swift 3 -> version 2.0.4
Swift 4 -> version 3.0.0
Swift 4.1 -> version 3.1.0
Swift 4.2 -> version 3.2.0
Swift 5.0 -> version 5.0.0
Swift 5.1 -> version 5.1.0
Swift 5.1.3 -> version 5.1.1

Backers

Like the project? Offer coffee or support us with a monthly donation and help us continue our activities :)

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site :)

Comments
  • Regression regarding `resolveOnMainThread `

    Regression regarding `resolveOnMainThread `

    Obviously, this is not a bug per se, but it is worth noting that v2.0.3 breaks a lot of existing code by deallocating prematurely when the first promise is not retained manually (for example in nested functions)... Something like:

    func fetchData() {
    	
    	showLoading()
    	
    	func fetch() -> Promise<Something> {
    		...
    	}
    	
    	fetch().resolveOnMainThread()
    	.then { data in
    		...
    	}
    	.onError { error in
    		...
    	}
    	.finally { [weak self] in
    		self?.hideLoading()
    	}
    	
    }
    
    opened by alladinian 8
  • Support keypath in typed calls

    Support keypath in typed calls

    Hey @s4cha! What do you think of adding a resource keypath in ws calls? It's similar to what is implemented in RestKit objects mapping.

    Consider the following server response:

    {
         count: 2,
         articles: [
              {
                   id: 1,
                   name: "Foo"
              },
              {
                   id: 2,
                   name: "Bar"
              }
         ],
         error: 
              { 
                   code: 0,
                   message: "Test" 
              }
    }
    

    It would be great to be able to parse it like this:

    ws.get("/articles", params: ["category": name], keypath: "articles").then { articles in 
        // articles = ["Foo", "Bar"]
    }.onError { error in 
        // error = "Test"
    }
    

    I am aware of the jsonParsingSingleResourceKey and jsonParsingColletionKey, they seem to fulfil the need partially, but if the key is different for different calls, it requires additional setup to be made. As for response error handling, its mapping description could be added globally to WS class similar to jsonParsingSingleResourceKey, specifying the keypath and maybe a custom error class or something like this to be able to parse the specific error format returned by server.

    Currently it requires to write a wrapper function like this:

    func get<T: ArrowParsable>(path: String, params: [String: AnyObject] = [:], keypath: String? = nil) -> Promise<T> {
        return Promise<T>(callback: { (resolve, reject) in
            ws.get(path, params: params)
                .then({ (json: JSON) in
                    if let error = NSError(json: json) {
                        reject(error)
                    } else {
                        resolve(self.modelFromJSON(json, key: keypath))
                    }
                })
                .onError({ (error) in
                    reject(error)
                })
        })
    }
    
    opened by maxkonovalov 8
  • Post promise error

    Post promise error

    Hi, first, thanks for your good job! (especially with Stevia 👍 )

    I wanted to use your lib (v2.0.4) to post some datas but...

    When I try this:

    import Arrow
    import then
    import ws
    
    let ws = WS("")
    ws.post("", params: ["":""]).then { json in }
    

    Produce error: Ambiguous use of 'post(_:params:)'

    And when used like in the get example:

    func test() -> Promise<JSON> {
            return ws.post("", params: ["":""])
    }
    

    Produce error: No 'post' candidates produce the expected contextual result type 'Promise'

    Any ideas? Did I miss something?

    Tell me if I can help!

    Merci :)

    opened by AlbanPerli 6
  • Upload App Store Unsupport arm64

    Upload App Store Unsupport arm64

    I use ws 1.1.5

    I can not upgrade to 1.3, because It stops working because all my application, I prefer to only use this version

    Cartfile.resolved

    github "Alamofire/Alamofire" "3.2.1" github "s4cha/Arrow" "0.7.6" github "stephencelis/SQLite.swift" "0.10.1" github "s4cha/then" "2.0.1" github "s4cha/ws" "1.1.5"

    I use command carthage update

    Carthage/Checkouts/ws/ws/WS.swift:13:8: error: module file was created by a newer version of the compiler: /Carthage/Checkouts/ws/Carthage/Build/iOS/then.framework/Modules/then.swiftmodule/arm64.swiftmodule A shell task (/usr/bin/xcrun xcodebuild -project //Carthage/Checkouts/ws/ws.xcodeproj -scheme ws -configuration Release -sdk iphoneos ONLY_ACTIVE_ARCH=NO BITCODE_GENERATION_MODE=bitcode CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES clean build) failed with exit code 65: ** BUILD FAILED **

    Old projects this version was used github "s4cha/then" "1.4.0"

    with ws 1.1.5, now automatically change to github "s4cha/then" "2.0.1"

    why?

    opened by ZephiroRB 6
  • Extending PUT

    Extending PUT

    Hello Sacha,

    Loving this library so far :-).

    I'm quite a n00b to this and was hoping you could help me out with extending one of the functions:

    What I essentially need is to extend ws.put to take different parameters, instead of params: [String : AnyObject], I would like it to take params: [String : Any]

    I looked in the WS+Requests.swift but couldn't get it to work because the returned call function doesn't exist.

    Reason I need this is because when I PUT a boolean as paramater, the AnyObject returns a 0 or a 1, while the API that I am putting to only takes true or false. The API i'm posting to is the philips Hue 2.0 bridge.

    Looking very much forward to your replay :).

    Kind Regards,

    Andre Vink

    opened by vinkcode 6
  • POST params as JSON?

    POST params as JSON?

    How can I serialize POST params as JSON?

    Let's say we have save() like this

    func save() -> Promise<MyModel> {
        return ws.post("/mymodels", params: ["data": ["date": startingDate, "number": 123]])
    }
    

    Log output is

    POST /mymodels
    params : ["data": {
        date = "2016-04-21 18:26:53 +0000";
        number = 123;
    }]
    CODE: 400
    

    So params should be something like

    {
      "data": {
        "date" = "2016-04-21 18:26:53 +0000",
        "number" = 123
      }
    }
    

    Can this be accomplished easily with ws, or should I be looking for alternatives or plain Alamofire?

    opened by stami 6
  • Handle double parameters for multipart request

    Handle double parameters for multipart request

    I send a multipart request with a picture and other parameters. The string ones work but the Double ones don't. I checked the file WSRequest.swift in method func sendMultipartRequest(_ resolve: @escaping (_ result: (Int, [AnyHashable: Any], JSON)) -> Void, reject: @escaping (_ error: Error) -> Void, progress:@escaping (Float) -> Void)

    I add the double case like this :

    for (key, value) in self.params {
    	if let int = value as ? Int {
    		let str = "\(int)"
    		if let d = str.data(using: String.Encoding.utf8) {
    			formData.append(d, withName: key)
    		}
    	} else if
    	let double = value as ? Double {
    		let str = "\(double)"
    		if let d = str.data(using: String.Encoding.utf8) {
    			formData.append(d, withName: key)
    		}
    	} else {
    		if let str = value as ? String, let data = str.data(using: String.Encoding.utf8) {
    			formData.append(data, withName: key)
    		}
    	}
    }
    

    Would be cool if you could fix it officially

    opened by LivioGama 4
  • Add CocoaPods Podspec

    Add CocoaPods Podspec

    Hi Sacha. This pull request adds support for CocoaPods. I had to rename import then to import thenPromise. I see you have the Cartfile locked to a specific commit...was this because of the renaming of then? If so, we should update that to the right version.

    Thanks!

    opened by adolfo 4
  • Carthage frameworks

    Carthage frameworks

    There are errors when submitting an archive that contains ws framework added via Carthage:

    screen-shot-2

    This is caused by ws.framework containing its own Frameworks folder. I guess, that's because of the "Run Script" build phase included in ws target, which also results in including then.framework twice when submitting the build:

    screen-shot-1

    I worked around the issue by adding a "Run Script" build phase in the host app's target to remove the nested "Frameworks" folder:

    cd "${SRCROOT}/Carthage/Build/iOS/ws.framework"
    if [[ -d "Frameworks" ]]; then
    rm -fr Frameworks
    fi
    

    But it would be great if it could be fixed directly in the framework 😉

    opened by maxkonovalov 4
  • When will swift5 be supported?

    When will swift5 be supported?

    When I tried to use the ws framework, I found that it relied on Then and Arrow libraries, but neither of them supported swift5. Now that swift5 has been released for so long, I really hope to update it to support swift5 soon. Thanks.

    opened by arden 3
  • Log levels

    Log levels

    Hey, great framework, I really enjoy using it :) Would be nice though to add logging levels or at least an ability to temporarily disable the console logs for ws. Also the same response is printed twice if Promise with custom model object is returned, which seems unnecessary.

    opened by maxkonovalov 3
  • SPM package is broken for Xcode12

    SPM package is broken for Xcode12

    Hi there, since Xcode12 drops support for iOS8, ws fails to build on Xcode12 with the following error:

    Target Integrity: The package product 'Alamofire' requires minimum platform version 9.0 for the iOS platform, but this target supports 8.0

    Are you planning an updated version/branch with iOS9 deployment target, or would be safe to fork and link edited/forked version in the project (I understand that there is a new, successor to this project) ?

    opened by alladinian 0
  • Supporting multiple multipart data

    Supporting multiple multipart data

    How can I request with multiple multipart data. As i can see that existing methods doesn't seems to be providing this. Am I missing something?

    In WS.Swift file open func postMultipart(_ url: String, params: Params = Params(), name: String, data: Data, fileName: String, mimeType: String) -> Promise { let r = postMultipartRequest(url, params: params, name: name, data: data, fileName: fileName, mimeType: mimeType) return r.fetch().resolveOnMainThread() }

    and request in WS+Requests.swift

    public func postMultipartRequest(_ url: String, params: Params = Params(), name: String, data: Data, fileName: String, mimeType: String) -> WSRequest { let c = call(url, verb: .post, params: params) c.isMultipart = true c.multipartData = data c.multipartName = name c.multipartFileName = fileName c.multipartMimeType = mimeType return c }

    opened by VikkyTheDev 0
  • Usage in an extension

    Usage in an extension

    Getting this when trying to use inside an extension 'shared' is unavailable in application extensions for iOS: Use view controller based solutions where appropriate instead.

    I comment out everything in that function and it compiles fine

        func tick() {
    //        let previousValue = UIApplication.shared.isNetworkActivityIndicatorVisible
    //        let newValue = (runningRequests > 0)
    //        if newValue != previousValue {
    //            UIApplication.shared.isNetworkActivityIndicatorVisible = newValue
    //        }
        }
    
    opened by andrewvmail 0
  • Auth Header Bearer Token refresh, AF5 beta

    Auth Header Bearer Token refresh, AF5 beta

    Before each call, I need to check if my bearer token is still OK, and if not get a new one, and then set it in the headers.

    I looked into the code, it will be trivial to add a RequestAdapter to ws - as supported by Alamofire 4 - and that could do that except not asynchronously. So I'd still get occasional errors when the token isn't refreshed in time. And I'd have to deal with those errors on a code level which kind of destroys the elegance and simplicity of using ws.

    AlamoFire 5 has a built in solution for this exact problem.

    I have two questions

    • Has anybody looked into upgrading to AlamoFire 5 (currently in beta)? That would allow for asynchronous bearer token refresh, making what I need trivial to implement. They added a callback to RequestAdapter - super easy to use.

    • Is there another good way you can think of to provide a feature similar to AF5 callback based RequestAdapter? Didn't really see one...

    As ws library is concerned upgrading to AF5 is probably the best way to go about it.

    opened by n13 2
  • REFRESH REQUEST

    REFRESH REQUEST

    Hi, When interacting with OAuth Transparent token refresh is almost always desired.

    As WS stands on the shoulder of Alamofire, and Alamofire v4 supports a new RequestRetrier protocol, how can I configure WS so that when my authentication token expires I get a new one and retry the request?

    Thanks!

    opened by lernamanto 1
Releases(5.1.3)
Owner
Fresh
Simple iOS tools to solve problems 99% of us have.
Fresh
An Alamofire extension which converts JSON response data into swift objects using EVReflection

AlamofireJsonToObjects ?? This is now a subspec of EVReflection and the code is maintained there. ?? You can install it as a subspec like this: use_fr

Edwin Vermeer 161 Sep 29, 2022
A barebones Swift HTTP client with automatic JSON response parsing.

HTTP Client A barebones Swift HTTP client with automatic JSON response parsing. Installation Add HTTP Client as a dependency through Xcode or directly

Joe Masilotti 30 Oct 11, 2022
Malibu is a networking library built on promises

Description Palm trees, coral reefs and breaking waves. Welcome to the surf club Malibu, a networking library built on promises. It's more than just a

Vadym Markov 410 Dec 30, 2022
Malibu is a networking library built on promises

Description Palm trees, coral reefs and breaking waves. Welcome to the surf club Malibu, a networking library built on promises. It's more than just a

HyperRedink 10 Jan 29, 2022
Lightweight network abstraction layer, written on top of Alamofire

TRON is a lightweight network abstraction layer, built on top of Alamofire. It can be used to dramatically simplify interacting with RESTful JSON web-

MLSDev 528 Dec 26, 2022
Restofire is a protocol oriented networking client for Alamofire

Restofire is a protocol oriented networking client for Alamofire. Features Requirements Installation Usage License Features Global Configuration for h

Restofire 381 Sep 29, 2022
A progressive download manager for Alamofire

ALDownloadManager A progressive download manager for Alamofire (Alamofire下载器) The default support breakpoint continues. Sequential Download(顺序下载 ) Dow

null 48 May 1, 2022
Alamofire network layer

NVNetworkRequest Alamofire network layer Installation Add this to your Package dependencies: dependencies: [ .package(url: "https://github.com/vin

Vinh Nguyen 0 Nov 19, 2021
Advanced Networking Layer Using Alamofire with Unit Testing

Advanced Networking Layer Using Alamofire with Unit Testing

Ali Fayed 8 May 23, 2022
Bamboots - Extension 4 Alamofire

Bamboots is a network request framework based on Alamofire , aiming at making network request easier for business development. Protocols Features Requ

mmoaay 442 Dec 22, 2022
Simple REST Client based on RxSwift and Alamofire.

RxRestClient Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 10.0+ tvOS 10.

STDev 16 Nov 19, 2022
EasyImplementationAlamoFire - An iOS project to demonstrate the usage of Alamofire in an efficient and organised way.

EasyImplementationAlamoFire Tutorial to demonstrate an efficient way of handling the APIs structure for your iOS Applications. Prerequisites Swift 5 X

null 0 Jan 3, 2022
Alamofire extension for serialize NSData to SwiftyJSON

Alamofire-SwiftyJSON An extension to make serializing Alamofire's response with SwiftyJSON easily. ⚠️ To use with Swift 3.x please ensure you are usin

SwiftyJSON 1.4k Dec 22, 2022
Simple REST Client based on RxSwift and Alamofire.

RxRestClient Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 10.0+ tvOS 10.

STDev 16 Nov 19, 2022
Alamofire Network Layer written in swift 5 using the protocol oriented, combine, UIKit, MVVM.

CoreAPI-iOS This project Contains Alamofire Network layer Based on Protocol Oriented Concept and Combine Framework. It is created with UIKit, Alamofir

Mehran Kamalifard 27 Nov 11, 2022
A frida tool that capture GET/POST HTTP requests of iOS Swift library 'Alamofire' and disable SSL Pinning.

FridaHookSwiftAlamofire A frida tool that capture GET/POST HTTP requests of iOS Swift library 'Alamofire' and disable SSL Pinning. 中文文档及过程 Features Ca

neilwu 69 Dec 16, 2022
Lightweight Networking and Parsing framework made for iOS, Mac, WatchOS and tvOS.

NetworkKit A lightweight iOS, Mac and Watch OS framework that makes networking and parsing super simple. Uses the open-sourced JSONHelper with functio

Alex Telek 30 Nov 19, 2022
Parsing Simple HTTP Headers for swift

HTTP Headers Parsing simple HTTP headers using pre-defined header descriptions. Examples: let response = HTTPURLRseponse(..., headers: [ "X-RateLi

Alexander Grebenyuk 12 May 17, 2022
To practice URLSession to fetch json data from open weather API

⛅️ weatherApp-iOS-practice ?? 기능 상세 도시 이름을 입력하면 현재 날씨 정보를 가져와 화면에 표시되게 만들어야 합니다

Jacob Ko 0 Dec 18, 2021