Skip to content

Commit

Permalink
userInfo Network call
Browse files Browse the repository at this point in the history
  • Loading branch information
grenos committed Mar 29, 2020
1 parent 80450ed commit 4b2855c
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 10 deletions.
Binary file not shown.
73 changes: 73 additions & 0 deletions GHFollowers/Managers/NetworkManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ class NetworkManager {
private init() {}


// MARK: @escaping closure explenation
/*
Closures can be escaping or non escaping. If a closuse is escaping can 'outlive' the function that is declared in
It is used for asychronus operations (basically like a promise in JavaScript)
When we use an escaping closure we need to deal also with memory management (that why we use [weak self] on the return of the promise
*/


// MARK: Followers Call
func getFollowers(for username: String, page: Int, completed: @escaping(Result<[Follower], GFError>) -> Void) {
// set endpoint
let endpoint = baseUrl + "/users/\(username)/followers?per_page=100&page=\(page)"
Expand Down Expand Up @@ -80,9 +89,73 @@ class NetworkManager {

// start network call
task.resume()
}




// MARK: User Call
func getUserInfo(for username: String, completed: @escaping(Result<User, GFError>) -> Void) {
// set endpoint
let endpoint = baseUrl + "/users/\(username)"

// make sure endpoint is a valid string
guard let url = URL(string: endpoint) else {
// if not we need to pass an error message to the callback (completed)
// so our ViewController that calls that function can print the custom alert
// because we should print Views only from main thread

// call the callback and pass the error
completed(.failure(.invalidUsername))
return
}


// URL Session data task (call api)
let task = URLSession.shared.dataTask(with: url) { data, response, error in

// if error exists and its not nil
// this error will return if the network call wasn't even made
if let _ = error {
completed(.failure(.unableToComplete))
return
}

// if response exists and is not nil and if status code is 200(OK)
// cast it as a HTTPURLResponse adn save in the variable
// ELSE call completed with the error string
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
completed(.failure(.invalidResponse))
return
}

// check if the data response is good and save in the variable data
// else call completed
guard let data = data else {
completed(.failure(.invalidData))
return
}

// Decode JSON file and place it in model
do {
let decoder = JSONDecoder()
// convert keys from snake_case to camelCase
decoder.keyDecodingStrategy = .convertFromSnakeCase
// array we want to create its type from the data constant from above
let user = try decoder.decode(User.self, from: data)
// if all ok call the completed callback, passing the array and nil for error
completed(.success(user))

} catch {
// if the decoder above throws
completed(.failure(.invalidData))
}


}

// start network call
task.resume()
}

}
18 changes: 9 additions & 9 deletions GHFollowers/Model/User.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@
import Foundation


struct User {
struct User: Codable {

var login: String
var avatarUrl: String
let login: String
let avatarUrl: String
var name: String?
var location: String?
var bio: String?
var publicRepos: Int
var publicGists: Int
var htmlUrl: String
var following: Int
var followers: Int
var createdAt: String
let publicRepos: Int
let publicGists: Int
let htmlUrl: String
let following: Int
let followers: Int
let createdAt: String
}
16 changes: 15 additions & 1 deletion GHFollowers/Screens/UserInfoVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,21 @@ class UserInfoVC: UIViewController {
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissVC))
// add button to navigation bar
navigationItem.rightBarButtonItem = doneButton
print(username!)


NetworkManager.shared.getUserInfo(for: username) { [weak self] result in
guard let self = self else {return}

switch result {
case .success(let user):
print(user)
case .failure(let error):
self.presentGFAlertOnMainThread(title: "Something went wrong", message: error.rawValue, buttonTitle: "Ok")
}


}

}

@objc func dismissVC() {
Expand Down

0 comments on commit 4b2855c

Please sign in to comment.