I am starting to use RxSwift to make the service call.
This was my old code:
class Service: GraphQLService {
func graphQL(body: [String: Any?], onSuccess: #escaping (Foundation.Data) throws -> (), onFailure: #escaping (Error) -> ()) {
guard let urlValue = Bundle.main.urlValue else { return }
guard let url = URL(string: urlValue) else { return
print("Error with info.plist")
}
var request = URLRequest(url: url)
let userKey = Bundle.main.userKeyValue
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(userKey, forHTTPHeaderField: "userid")
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed)
URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
onFailure(error)
}
if let data = data {
do{
try onSuccess(data)
}
catch{
onFailure(error)
}
}
}.resume()
}
And here I do the function to get time deposits:
final class TimeDepositManager: Service, TimeDepositManagerProtocol {
let timeDepositQuery = Bundle.main.queryValue
func getTimeDeposits(onSuccess: #escaping ([TimeDeposits]) -> (), onFailure: #escaping (Error) -> ()) {
let body = ["query": timeDepositQuery]
Service().graphQL(body: body, onSuccess: { data in
let json = try? JSONDecoder().decode(GraphQLResponse.self, from: data)
onSuccess(json?.data?.account?.timeDeposits ?? [])
}, onFailure: onFailure)
}
And so far this is my code with RxSwift:
class Service: GraphQLService {
func graphQL(body: [String : Any?]) -> Observable<Foundation.Data> {
return Observable.create { observer in
let urlValue = Bundle.main.urlValue
let url = URL(string: urlValue ?? "")
let session = URLSession.shared
var request = URLRequest(url: url!)
let userKey = Bundle.main.userKeyValue
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(userKey, forHTTPHeaderField: "userid")
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed)
session.dataTask(with: request) { (data, response, error) in
if let error = error {
observer.onError(error)
}
if let data = data {
do{
try onSuccess(data)
observer.onNext(data)
}
catch{
//onFailure(error)
observer.onError(error)
print("Error: \(error.localizedDescription)")
}
}
}.resume()
return Disposables.create {
session.finishTasksAndInvalidate()
}
}
}
This is where I don't understand how in my getTimeDeposits () I can do the deserialization with try? JSONDecoder () ... with RxSwift without using onSuccess?
final class TimeDepositManager: Service, TimeDepositManagerProtocol {
let timeDepositQuery = Bundle.main.queryValue
func getTimeDeposits() -> Observable<[TimeDeposits]> {
let body = ["query": timeDepositQuery]
Service().graphQL(body: body)
}
You can have getTimeDeposits() return an Observable as well and handle the deserialization in a map closure. A couple of other things.
RxCocoa already has a method on URLSession so you don't need to write your own.
I suggest reducing the amount of code you have in a function that makes the network request. You want to be able to test your logic for making the request without actually making it.
Something like this:
final class TimeDepositManager: Service, TimeDepositManagerProtocol {
let timeDepositQuery = Bundle.main.queryValue
func getTimeDeposits() -> Observable<[TimeDeposits]> {
let body = ["query": timeDepositQuery]
return Service().graphQL(body: body)
.map { try JSONDecoder().decode(GraphQLResponse.self, from: $0).data?.account?.timeDeposits ?? [] }
}
}
class Service: GraphQLService {
func graphQL(body: [String: Any?]) -> Observable<Data> {
guard let urlValue = Bundle.main.urlValue else { fatalError("Error with info.plist") }
let request = urlRequest(urlValue: urlValue, body: body)
return URLSession.shared.rx.data(request: request) // this is in RxCocoa
}
func urlRequest(urlValue: String, body: [String: Any?]) -> URLRequest {
guard let url = URL(string: urlValue) else { fatalError("Error with urlValue") }
var request = URLRequest(url: url)
let userKey = Bundle.main.userKeyValue
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(userKey, forHTTPHeaderField: "userid")
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed)
return request
}
}
If you don't want to use RxCocoa for some reason, here is the correct way to wrap the URLSession.dataTask method:
extension URLSession {
func data(request: URLRequest) -> Observable<Data> {
Observable.create { observer in
let task = self.dataTask(with: request, completionHandler: { data, response, error in
guard let response = response as? HTTPURLResponse else {
observer.onError(URLError.notHTTPResponse(data: data, response: response))
return
}
guard 200 <= response.statusCode && response.statusCode < 300 else {
observer.onError(URLError.failedResponse(data: data, response: response))
return
}
guard let data = data else {
observer.onError(error ?? RxError.unknown)
return
}
observer.onNext(data)
observer.onCompleted() // be sure to call `onCompleted()` when you are done emitting values.
// make sure every possible path through the code calls some method on `observer`.
})
return Disposables.create { task.cancel() } // don't forget to handle cancelation properly. You don't want to kill *all* tasks, just this one.
}
}
}
enum URLError: Error {
case notHTTPResponse(data: Data?, response: URLResponse?)
case failedResponse(data: Data?, response: HTTPURLResponse)
}
I'm trying to use Swift to make a GET call to a REST API, and have tried to follow numerous tutorials, but can't figure it out. Either because I cannot figure out how to translate all the Obj-C to Swift, or because half of the methods n' such are deprecated. Does anyone know how to make the call, and parse returned JSON data?
Swift 5 & 4
let params = ["username":"john", "password":"123456"] as Dictionary<String, String>
var request = URLRequest(url: URL(string: "http://localhost:8080/api/1/login")!)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject: params, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
print(response!)
do {
let json = try JSONSerialization.jsonObject(with: data!) as! Dictionary<String, AnyObject>
print(json)
} catch {
print("error")
}
})
task.resume()
You can do like this :
var url : String = "http://google.com?test=toto&test2=titi"
var request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
if (jsonResult != nil) {
// process jsonResult
} else {
// couldn't load JSON, look at error
}
})
EDIT : For people have problem with this maybe your JSON stream is an
array [] and not an object {} so you have to change jsonResult to
NSArray instead of NSDictionary
I think the NSURLSession api fits better in this situation. Because if you write swift code your project target is at least iOS 7 and iOS 7 supports NSURLSession api. Anyway here is the code
let url = "YOUR_URL"
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)) { data, response, error in
// Handle result
}.resume()
Here is the complete code for REST API requests using NSURLSession in swift
For GET Request
let configuration = NSURLSessionConfiguration .defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration)
let urlString = NSString(format: "your URL here")
print("get wallet balance url string is \(urlString)")
//let url = NSURL(string: urlString as String)
let request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: NSString(format: "%#", urlString) as String)
request.HTTPMethod = "GET"
request.timeoutInterval = 30
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let dataTask = session.dataTaskWithRequest(request) {
(let data: NSData?, let response: NSURLResponse?, let error: NSError?) -> Void in
// 1: Check HTTP Response for successful GET request
guard let httpResponse = response as? NSHTTPURLResponse, receivedData = data
else {
print("error: not a valid http response")
return
}
switch (httpResponse.statusCode)
{
case 200:
let response = NSString (data: receivedData, encoding: NSUTF8StringEncoding)
print("response is \(response)")
do {
let getResponse = try NSJSONSerialization.JSONObjectWithData(receivedData, options: .AllowFragments)
EZLoadingActivity .hide()
// }
} catch {
print("error serializing JSON: \(error)")
}
break
case 400:
break
default:
print("wallet GET request got response \(httpResponse.statusCode)")
}
}
dataTask.resume()
For POST request ...
let configuration = NSURLSessionConfiguration .defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration)
let params = ["username":bindings .objectForKey("username"), "provider":"walkingcoin", "securityQuestion":securityQuestionField.text!, "securityAnswer":securityAnswerField.text!] as Dictionary<String, AnyObject>
let urlString = NSString(format: “your URL”);
print("url string is \(urlString)")
let request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: NSString(format: "%#", urlString)as String)
request.HTTPMethod = "POST"
request.timeoutInterval = 30
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(params, options: [])
let dataTask = session.dataTaskWithRequest(request)
{
(let data: NSData?, let response: NSURLResponse?, let error: NSError?) -> Void in
// 1: Check HTTP Response for successful GET request
guard let httpResponse = response as? NSHTTPURLResponse, receivedData = data
else {
print("error: not a valid http response")
return
}
switch (httpResponse.statusCode)
{
case 200:
let response = NSString (data: receivedData, encoding: NSUTF8StringEncoding)
if response == "SUCCESS"
{
}
default:
print("save profile POST request got response \(httpResponse.statusCode)")
}
}
dataTask.resume()
I hope it works.
edited for swift 2
let url = NSURL(string: "http://www.test.com")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
print(NSString(data: data!, encoding: NSUTF8StringEncoding))
}
task.resume()
Swift 4 - GET request
var request = URLRequest(url: URL(string: "http://example.com/api/v1/example")!)
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in
do {
let jsonDecoder = JSONDecoder()
let responseModel = try jsonDecoder.decode(CustomDtoClass.self, from: data!)
print(responseModel)
} catch {
print("JSON Serialization error")
}
}).resume()
Don't forget to configure App Transport Security Settings to add your domain to the exceptions and allow insecure http requests if you're hitting endpoints without using HTTPS.
You can use a tool like http://www.json4swift.com/ to autogenerate your Codeable Mappings from your JSON responses.
In swift 3.3 and 4. I crated APIManager class with two public methods. Just pass required parameter, api name and request type. You will get response then pass it to the closure.
import UIKit
struct RequestType {
static let POST = "POST"
static let GET = "GET"
}
enum HtttpType: String {
case POST = "POST"
case GET = "GET"
}
class APIManager: NSObject {
static let sharedInstance: APIManager = {
let instance = APIManager()
return instance
}()
private init() {}
// First Method
public func requestApiWithDictParam(dictParam: Dictionary<String,Any>, apiName: String,requestType: String, isAddCookie: Bool, completionHendler:#escaping (_ response:Dictionary<String,AnyObject>?, _ error: NSError?, _ success: Bool)-> Void) {
var apiUrl = “” // Your api url
apiUrl = apiUrl.appendingFormat("%#", apiName)
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = URL(string: apiUrl)!
let HTTPHeaderField_ContentType = "Content-Type"
let ContentType_ApplicationJson = "application/json"
var request = URLRequest.init(url: url)
request.timeoutInterval = 60.0
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
request.addValue(ContentType_ApplicationJson, forHTTPHeaderField: HTTPHeaderField_ContentType)
request.httpMethod = requestType
print(apiUrl)
print(dictParam)
let dataTask = session.dataTask(with: request) { (data, response, error) in
if error != nil {
completionHendler(nil, error as NSError?, false)
} do {
let resultJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
print("Request API = ", apiUrl)
print("API Response = ",resultJson ?? "")
completionHendler(resultJson, nil, true)
} catch {
completionHendler(nil, error as NSError?, false)
}
}
dataTask.resume()
}
// Second Method
public func requestApiWithUrlString(param: String, apiName: String,requestType: String, isAddCookie: Bool, completionHendler:#escaping (_ response:Dictionary<String,AnyObject>?, _ error: NSError?, _ success: Bool)-> Void ) {
var apiUrl = "" // Your api url
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
var request: URLRequest?
if requestType == "GET" {
apiUrl = String(format: "%#%#&%#", YourAppBaseUrl,apiName,param)
apiUrl = apiUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
print("URL=",apiUrl)
let url = URL(string: apiUrl)!
request = URLRequest.init(url: url)
request?.httpMethod = "GET"
} else {
apiUrl = String(format: "%#%#", YourAppBaseUrl,apiName)
apiUrl = apiUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
print("URL=",apiUrl)
let bodyParameterData = param.data(using: .utf8)
let url = URL(string: apiUrl)!
request = URLRequest(url: url)
request?.httpBody = bodyParameterData
request?.httpMethod = "POST"
}
request?.timeoutInterval = 60.0
request?.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
request?.httpShouldHandleCookies = true
let dataTask = session.dataTask(with: request!) { (data, response, error) in
if error != nil {
completionHendler(nil, error as NSError?, false)
} do {
if data != nil {
let resultJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
print("Request API = ", apiUrl)
print("API Response = ",resultJson ?? "")
completionHendler(resultJson, nil, true)
} else {
completionHendler(nil, error as NSError?, false)
}
} catch {
completionHendler(nil, error as NSError?, false)
}
}
dataTask.resume()
}
}
// Here is example of calling Post API from any class
let bodyParameters = String(format: "appid=%#&appversion=%#","1","1")
APIManager.sharedInstance.requestApiWithUrlString(param: bodyParameters, apiName: "PASS_API_NAME", requestType: HtttpType.POST.rawValue, isAddCookie: false) { (dictResponse, error, success) in
if success {
if let dictMessage = dictResponse?["message"] as? Dictionary<String, AnyObject> {
// do you work
}
} else {
print("Something went wrong...")
}
}
}
/// Or just use simple function
func dataRequest() {
let urlToRequest = "" // Your API url
let url = URL(string: urlToRequest)!
let session4 = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let paramString = "data=Hello"
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session4.dataTask(with: request as URLRequest) { (data, response, error) in
guard let _: Data = data, let _: URLResponse = response, error == nil else {
print("*****error")
return
}
if let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) {
print("****Data: \(dataString)") //JSONSerialization
}
}
task.resume()
}
Swift 3.0
let request = NSMutableURLRequest(url: NSURL(string: "http://httpstat.us/200")! as URL)
let session = URLSession.shared
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
if error != nil {
print("Error: \(String(describing: error))")
} else {
print("Response: \(String(describing: response))")
}
})
task.resume()
Swift 4
Create an app using Alamofire with Api Post method
Install pod file -pod 'Alamofire', '~> 4.0' for Swift 3 with Xcode 9
Create Webservices.swift class, import Alamofire
Design storyBoard ,Login View
insert following Code for the ViewControllerClass
import UIKit
class ViewController: UIViewController {
#IBOutlet var usernameTextField: UITextField!
#IBOutlet var passwordTextField: UITextField!
var usertypeStr :String = "-----------"
var loginDictionary : NSDictionary?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func loginButtonClicked(_ sender: Any) {
WebServices.userLogin(userName: usernameTextField.text!, password: passwordTextField.text!,userType: usertypeStr) {(result, message, status )in
if status {
let loginDetails = result as? WebServices
self.loginDictionary = loginDetails?.loginData
if self.loginDictionary?["status"] as? String == "error"
{
self.alertMessage(alerttitle: "Login Error", (self.loginDictionary?["message"] as? String)!)
} else if self.loginDictionary?["status"] as? String == "ok" {
self.alertMessage(alerttitle: "", "Success")
}else {
self.alertMessage(alerttitle: "", (self.loginDictionary?["message"] as? String)!)
}
} else {
self.alertMessage(alerttitle: "", "Sorry")
}
}
}
func alertMessage(alerttitle:String,_ message : String){
let alertViewController = UIAlertController(title:alerttitle, message:message, preferredStyle: .alert)
alertViewController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alertViewController, animated: true, completion: nil)
}
}
Insert Following Code For WebserviceClass
import Foundation
import Alamofire
class WebServices: NSObject {
enum WebServiceNames: String {
case baseUrl = "https://---------------"
case UserLogin = "------------"
}
// MARK: - Login Variables
var loginData : NSDictionary?
class func userLogin(userName: String,password : String,userType : String, completion : #escaping (_ response : AnyObject?, _ message: String?, _ success : Bool)-> ()) {
let url = WebServiceNames.baseUrl.rawValue + WebServiceNames.UserLogin.rawValue
let params = ["USER": userName,"PASS":password,"API_Key" : userType]
WebServices.postWebService(urlString: url, params: params as [String : AnyObject]) { (response, message, status) in
print(response ?? "Error")
let result = WebServices()
if let data = response as? NSDictionary {
print(data)
result.loginData = data
completion(result, "Success", true)
}else {
completion("" as AnyObject?, "Failed", false)
}
}
}
//MARK :- Post
class func postWebService(urlString: String, params: [String : AnyObject], completion : #escaping (_ response : AnyObject?, _ message: String?, _ success : Bool)-> Void) {
alamofireFunction(urlString: urlString, method: .post, paramters: params) { (response, message, success) in
if response != nil {
completion(response as AnyObject?, "", true)
}else{
completion(nil, "", false)
}
}
}
class func alamofireFunction(urlString : String, method : Alamofire.HTTPMethod, paramters : [String : AnyObject], completion : #escaping (_ response : AnyObject?, _ message: String?, _ success : Bool)-> Void){
if method == Alamofire.HTTPMethod.post {
Alamofire.request(urlString, method: .post, parameters: paramters, encoding: URLEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
print(urlString)
if response.result.isSuccess{
completion(response.result.value as AnyObject?, "", true)
}else{
completion(nil, "", false)
}
}
}else {
Alamofire.request(urlString).responseJSON { (response) in
if response.result.isSuccess{
completion(response.result.value as AnyObject?, "", true)
}else{
completion(nil, "", false)
}
}
}
}
//Mark:-Cancel
class func cancelAllRequests()
{
Alamofire.SessionManager.default.session.getTasksWithCompletionHandler { dataTasks, uploadTasks, downloadTasks in
dataTasks.forEach { $0.cancel() }
uploadTasks.forEach { $0.cancel() }
downloadTasks.forEach { $0.cancel() }
}
}
}
swift 4
USE ALAMOFIRE in our App plz install pod file
pod 'Alamofire', '~> 4.0'
We can Use API for Json Data -https://swapi.co/api/people/
Then We can create A networking class for Our project- networkingService.swift
import Foundation
import Alamofire
typealias JSON = [String:Any]
class networkingService{
static let shared = networkingService()
private init() {}
func getPeople(success successblock: #escaping (GetPeopleResponse) -> Void)
{
Alamofire.request("https://swapi.co/api/people/").responseJSON { response in
guard let json = response.result.value as? JSON else {return}
// print(json)
do {
let getPeopleResponse = try GetPeopleResponse(json: json)
successblock(getPeopleResponse)
}catch{}
}
}
func getHomeWorld(homeWorldLink:String,completion: #escaping(String) ->Void){
Alamofire.request(homeWorldLink).responseJSON {(response) in
guard let json = response.result.value as? JSON,
let name = json["name"] as? String
else{return}
completion(name)
}
}
}
Then Create NetworkingError.swift class
import Foundation
enum networkingError : Error{
case badNetworkigStuff
}
Then create Person.swift class
import Foundation
struct Person {
private let homeWorldLink : String
let birthyear : String
let gender : String
let haircolor : String
let eyecolor : String
let height : String
let mass : String
let name : String
let skincolor : String
init?(json : JSON) {
guard let birthyear = json["birth_year"] as? String,
let eyecolor = json["eye_color"] as? String,
let gender = json["gender"] as? String,
let haircolor = json["hair_color"] as? String,
let height = json["height"] as? String,
let homeWorldLink = json["homeworld"] as? String,
let mass = json["mass"] as? String,
let name = json["name"] as? String,
let skincolor = json["skin_color"] as? String
else { return nil }
self.homeWorldLink = homeWorldLink
self.birthyear = birthyear
self.gender = gender
self.haircolor = haircolor
self.eyecolor = eyecolor
self.height = height
self.mass = mass
self.name = name
self.skincolor = skincolor
}
func homeWorld(_ completion: #escaping (String) -> Void) {
networkingService.shared.getHomeWorld(homeWorldLink: homeWorldLink){ (homeWorld) in
completion(homeWorld)
}
}
}
Then create DetailVC.swift
import UIKit
class DetailVC: UIViewController {
var person :Person!
#IBOutlet var name: UILabel!
#IBOutlet var birthyear: UILabel!
#IBOutlet var homeworld: UILabel!
#IBOutlet var eyeColor: UILabel!
#IBOutlet var skinColor: UILabel!
#IBOutlet var gender: UILabel!
#IBOutlet var hairColor: UILabel!
#IBOutlet var mass: UILabel!
#IBOutlet var height: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
print(person)
name.text = person.name
birthyear.text = person.birthyear
eyeColor.text = person.eyecolor
gender.text = person.gender
hairColor.text = person.haircolor
mass.text = person.mass
height.text = person.height
skinColor.text = person.skincolor
person.homeWorld{(homeWorld) in
self.homeworld.text = homeWorld
}
}
}
Then Create GetPeopleResponse.swift class
import Foundation
struct GetPeopleResponse {
let people : [Person]
init(json :JSON) throws {
guard let results = json["results"] as? [JSON] else { throw networkingError.badNetworkigStuff}
let people = results.map{Person(json: $0)}.flatMap{ $0 }
self.people = people
}
}
Then Our View controller class
import UIKit
class ViewController: UIViewController {
#IBOutlet var tableVieww: UITableView!
var people = [Person]()
#IBAction func getAction(_ sender: Any)
{
print("GET")
networkingService.shared.getPeople{ response in
self.people = response.people
self.tableVieww.reloadData()
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
guard segue.identifier == "peopleToDetails",
let detailVC = segue.destination as? DetailVC,
let person = sender as AnyObject as? Person
else {return}
detailVC.person = person
}
}
extension ViewController:UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return people.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = people[indexPath.row].name
return cell
}
}
extension ViewController:UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "peopleToDetails", sender: people[indexPath.row])
}
}
In our StoryBoard
plz Connect with our View with another one using segue with identifier -peopleToDetails
Use UITableView In our First View
Use UIButton For get the Data
Use 9 Labels in our DetailVc
Very simple 100% working , tested
var url : String = "https://restcountries.eu/rest/v2/all"
URLSession.shared.dataTask(with: NSURL(string: url) as! URL) { data, response, error in
// Handle result
let response = String (data: data!, encoding: String.Encoding.utf8)
print("response is \(response)")
do {
let getResponse = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
print(getResponse)
let countryArray = getResponse as! NSArray
print(countryArray)
let country1 = countryArray[0] as! [String:Any]
let name = country1["name"] as! String
print(name)
} catch {
print("error serializing JSON: \(error)")
}
}.resume()
}
If you're working in Swift 3, the syntax changes. The example here worked for me and has a good explanation of the steps: https://grokswift.com/simple-rest-with-swift/
This is the code from that tutorial:
let todoEndpoint: String = "https://jsonplaceholder.typicode.com/todos/1"
guard let url = URL(string: todoEndpoint) else {
print("Error: cannot create URL")
return
}
let urlRequest = URLRequest(url: url)
let task = session.dataTask(with: urlRequest) {
(data, response, error) in
// check for any errors
guard error == nil else {
print("error calling GET on /todos/1")
print(error!)
return
}
// make sure we got data
guard let responseData = data else {
print("Error: did not receive data")
return
}
// parse the result as JSON, since that's what the API provides
do {
guard let todo = try JSONSerialization.jsonObject(with: responseData, options: [])
as? [String: Any] else {
print("error trying to convert data to JSON")
return
}
// now we have the todo
// let's just print it to prove we can access it
print("The todo is: " + todo.description)
// the todo object is a dictionary
// so we just access the title using the "title" key
// so check for a title and print it if we have one
guard let todoTitle = todo["title"] as? String else {
print("Could not get todo title from JSON")
return
}
print("The title is: " + todoTitle)
} catch {
print("error trying to convert data to JSON")
return
}
}
task.resume()
Swift 5
API call method
//Send Request with ResultType<Success, Error>
func fetch(requestURL:URL,requestType:String,parameter:[String:AnyObject]?,completion:#escaping (Result<Any>) -> () ){
//Check internet connection as per your convenience
//Check URL whitespace validation as per your convenience
//Show Hud
var urlRequest = URLRequest.init(url: requestURL)
urlRequest.cachePolicy = .reloadIgnoringLocalCacheData
urlRequest.timeoutInterval = 60
urlRequest.httpMethod = String(describing: requestType)
urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
//Post URL parameters set as URL body
if let params = parameter{
do{
let parameterData = try JSONSerialization.data(withJSONObject:params, options:.prettyPrinted)
urlRequest.httpBody = parameterData
}catch{
//Hide hude and return error
completion(.failure(error))
}
}
//URL Task to get data
URLSession.shared.dataTask(with: requestURL) { (data, response, error) in
//Hide Hud
//fail completion for Error
if let objError = error{
completion(.failure(objError))
}
//Validate for blank data and URL response status code
if let objData = data,let objURLResponse = response as? HTTPURLResponse{
//We have data validate for JSON and convert in JSON
do{
let objResposeJSON = try JSONSerialization.jsonObject(with: objData, options: .mutableContainers)
//Check for valid status code 200 else fail with error
if objURLResponse.statusCode == 200{
completion(.success(objResposeJSON))
}
}catch{
completion(.failure(error))
}
}
}.resume()
}
Use of API call method
func useOfAPIRequest(){
if let baseGETURL = URL(string:"https://postman-echo.com/get?foo1=bar1&foo2=bar2"){
self.fetch(requestURL: baseGETURL, requestType: "GET", parameter: nil) { (result) in
switch result{
case .success(let response) :
print("Hello World \(response)")
case .failure(let error) :
print("Hello World \(error)")
}
}
}
}
Api Call using Model Class
let urlString = "http://--.154.--.78/------/index.php?route=api/coupon/all"
let url = URL(string: urlString)
var request = URLRequest(url: url!)
request.httpMethod = "GET"
URLSession.shared.dataTask(with:request) { (data, response, error) in
if error != nil {
print(error)
} else {
do {
let parsedDictionaryArray = try JSONSerialization.jsonObject(with: data!) as! [String:AnyObject]
print(parsedDictionaryArray)
if let arry = parsedDictionaryArray["data"] as? [[String:AnyObject]] {
for dic in arry {
let name = dic["name"]
let descriptionData = dic["description"]
self.modelReference.append(model(name: name as! String, descriptionStr: descriptionData as! String))
print(name!)
}
}
} catch let error as NSError {
print(error)
}
}
}.resume()
create a variable and connect with model class
var modelReference = [model]()
create a model class New -> swift class
import Foundation
class model : NSObject{
var name : String
var descriptionStr: String
init(name : String, descriptionStr: String)
{
self.name = name
self.descriptionStr = descriptionStr
}
}
then we can connect with our table view objects
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCellID")as! TableViewCell
cell.listName.text = modelReference[indexPath.row].name
let headers = [
"cache-control": "no-cache",
"postman-token": "6f8a-12c6-87a1-ac0f25d6385a"
]
let request = NSMutableURLRequest(url: NSURL(string: "Your url string")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if error == nil && data != nil {
do {
// Convert NSData to Dictionary where keys are of type String, and values are of any type
let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:AnyObject]
print(json)
//do your stuff
// completionHandler(true)
} catch {
// completionHandler(false)
}
}
else if error != nil
{
//completionHandler(false)
}
}).resume()
}
func getAPICalling(mainUrl:String) {
//create URL
guard let url = URL(string: mainUrl) else {
print("Error: cannot create URL")
return
}
//create request
let urlRequest = URLRequest(url: url)
// create the session
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
// make the request
let task = session.dataTask(with: urlRequest) {
(data, response, error) in
// check for any errors
guard error == nil else {
print("error calling GET")
print(error!.localizedDescription)
return
}
// make sure we got data
guard let responseData = data else {
print("error: did not receive data")
return
}
// convert Data in JSON && parse the result as JSON, since that's what the API provides
do {
guard let object = try JSONSerialization.jsonObject(with: responseData, options: [])
as? [String: Any] else {
print("error trying to convert data to JSON")
return
}
//JSON Response
guard let todoTitle = object["response"] as? NSDictionary else {
print("Could not get todo title from JSON")
return
}
//Get array in response
let responseList = todoTitle.value(forKey: "radioList") as! NSArray
for item in responseList {
let dic = item as! NSDictionary
let str = dic.value(forKey: "radio_des") as! String
self.arrName.append(str)
print(item)
}
DispatchQueue.main.async {
self.tblView.reloadData()
}
} catch {
print("error trying to convert data to JSON")
return
}
}
task.resume()
}
Usage:
getAPICalling(mainUrl:"https://dousic.com/api/radiolist?user_id=16")
class ApiManager: NSObject {
static func callGetDataApi(url: String,completion: #escaping([[String: Any]])-> Void) {
guard let url = URL(string: ApiName.baseUrl+url ) else { return }
var request = URLRequest(url: url)
request.httpMethod = "GET"
URLSession.shared.dataTask(with:request) { (data, response, error) in
if error != nil {
print(error ?? "")
} else {
do {
let arry = try JSONSerialization.jsonObject(with: data!) as! [[String:AnyObject]]
print(arry)
DispatchQueue.main.async {
completion(arry)
}
} catch let error as NSError {
print(error)
}
}
}.resume()
}
}