Almost every app needs to fetch data from the backend API or ‘server’. So, we will look at a basic approach to a network call in Swift.
Let’s check how can we implement API calling in swift. We will not be using any third parties or network calls instead, we will be using Apple’s own API services URLSession.
Things need to check before integrating API into the app :
URLSession
Completion Handlers
DispatchQueue
URLSession:
The URLSession is used to create URLSessionTalk instances, which can fetch and return data to your app, and download and upload files to web services.
Completion Handlers:
A completion handler in Swift is a function that calls back when a task completes.
DispatchQueue:
An object that manages the execution of tasks serially or concurrently on your app’s main thread or on a background thread.
Now let’s start working on API calling.
- Check the type of API. I am using the GET method for API calling.
- A JSON body to know what we are getting and documentation.
- API Key and URLs.
I am using below mentioned API you can check its data by hitting it in a browser.
https://swapi.dev/api/films/
Now based on the data we are getting from API create a Data Model.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Response: Codable{ let count: Int? let results: [Film] } class Film: Codable{ let title: String? let episode_id: Int? let opening_crawl : String? init(title:String, episode_id:Int, opening_crawl: String) { self.title = title self.episode_id = episode_id self.opening_crawl = opening_crawl } } |
Making a Network Call in Swift:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
func fetchFilms(completionHandler: @escaping([Film]) -> Void){ let url = URL(string: "https://swapi.dev/api/films/")! let task = URLSession.shared.dataTask(with: url, completionHandler:{(data,response,error) in if let error = error { print("error with fetching films: \(error)") return } guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else{ print("Error with the response, unexpected status code: \(response)") return } if let data = data, let filmSummary = try? JSONDecoder().decode(Response.self, from: data){ completionHandler(filmSummary.results) } }) task.resume(); } |
- We have used URLSession for making a network call by giving information to dataTask. Giving information to dataTask is called initialization.
- dataTask use completion handlers, and they always return the same types of information:
data
,response
anderror
. - We have handled this information accordingly. Cast the response to be an HTTP response & make decisions according to the status code returned by API.
- We are using the JSONDecoder to parse the data & show it nicely.
Finally call this function in viewDidLoad & show data on your screen accordingly.
FULL CODE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { private var films: [Film]? @IBOutlet weak var TestTableView: UITableView! override func viewDidLoad() { super.viewDidLoad() TestTableView.register(TextViewCell.nib, forCellReuseIdentifier: TextViewCell.identifier) TestTableView.dataSource = self TestTableView.delegate = self fetchFilms{ (films) in self.films = films print(films[0].opening_crawl ?? "") DispatchQueue.main.async { self.TestTableView.reloadData() } } // Do any additional setup after loading the view. } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return films?.count ?? 0 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: TextViewCell.identifier, for: indexPath) as! TextViewCell cell.titleLabel.text = films?[indexPath.row].title ?? "" return cell } } func fetchFilms(completionHandler: @escaping([Film]) -> Void){ let url = URL(string: "https://swapi.dev/api/films/")! let task = URLSession.shared.dataTask(with: url, completionHandler:{(data,response,error) in if let error = error { print("error with fetching films: \(error)") return } guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else{ print("Error with the response, unexpected status code: \(response)") return } if let data = data, let filmSummary = try? JSONDecoder().decode(Response.self, from: data){ completionHandler(filmSummary.results) } }) task.resume(); } class Response: Codable{ let count: Int? let results: [Film] } class Film: Codable{ let title: String? let episode_id: Int? let opening_crawl : String? init(title:String, episode_id:Int, opening_crawl: String) { self.title = title self.episode_id = episode_id self.opening_crawl = opening_crawl } } |
OUTPUT:
I have shown different film titles in a Tableview.
Conclusion:
In this article, I have explained API Calling in swift.
Thanks for reading this article ❤
If I got something wrong 🙈, let me know in the comments. I would love to improve.
For more interesting blogs check out here – https://mobikul.com/blog/
Reference link: https://www.freecodecamp.org/news/how-to-make-your-first-api-call-in-swift/