Skip to content

Commit

Permalink
avatarImageDownload networkManager refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
grenos committed Apr 12, 2020
1 parent 709b777 commit c0b7c87
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 50 deletions.
Binary file not shown.
7 changes: 6 additions & 1 deletion GHFollowers/Components/Cells/FavoriteCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ class FavoriteCell: UITableViewCell {
// setter for the favorite data
func set(favorite: Follower) {
usernameLabel.text = favorite.login
avatarImageView.downloadImage(from: favorite.avatarUrl)
NetworkManager.shared.downloadImage(from: favorite.avatarUrl) { [weak self](image) in
guard let self = self else { return }
DispatchQueue.main.async {
self.avatarImageView.image = image
}
}
}


Expand Down
7 changes: 6 additions & 1 deletion GHFollowers/Components/Cells/FollowerCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ class FollowerCell: UICollectionViewCell {
// on the FollowerListVC View Controller
func set(follower: Follower) {
usernameLabel.text = follower.login
avatarImageView.downloadImage(from: follower.avatarUrl)
NetworkManager.shared.downloadImage(from: follower.avatarUrl) { [weak self](image) in
guard let self = self else { return }
DispatchQueue.main.async {
self.avatarImageView.image = image
}
}
}


Expand Down
44 changes: 0 additions & 44 deletions GHFollowers/Components/ImageViews/GFAvatarImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,48 +30,4 @@ class GFAvatarImageView: UIImageView {
image = placeholderImage
translatesAutoresizingMaskIntoConstraints = false
}

func downloadImage(from urlString: String) {

// convert urlString to NSString
let cacheKey = NSString(string: urlString)

// cacheKey already cached then return and dont download
if let image = cache.object(forKey: cacheKey) {
self.image = image
return
}

// else go down here and download the image

// if param is not valid url return
guard let url = URL(string: urlString) else { return }

// make api call
let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in

guard let self = self else { return }

// if calls returns error return
if error != nil { return }
//if response exists and is not nil and if status code is 200(OK)
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else { return }
// check if we actually have data returned
guard let data = data else { return }

// pass the server data to the image
guard let image = UIImage(data: data) else { return }

// save downloaded image to chache
self.cache.setObject(image, forKey: cacheKey)

// get on the main thread to update UI
DispatchQueue.main.async {
self.image = image
}

}

task.resume()
}
}
12 changes: 11 additions & 1 deletion GHFollowers/Components/ViewControllers/GFUserInfoheaderVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class GFUserInfoheaderVC: UIViewController {


func configureUIElements() {
avatarImageView.downloadImage(from: user.avatarUrl)
downloadAvatarImage()
usernameLabel.text = user.login
nameLabel.text = user.name ?? "" // nil coalescing (if null then use placeholder in string)
locationLabel.text = user.location ?? "No Location"
Expand All @@ -53,6 +53,16 @@ class GFUserInfoheaderVC: UIViewController {
}


func downloadAvatarImage() {
NetworkManager.shared.downloadImage(from: user.avatarUrl) { [weak self](image) in
guard let self = self else { return }
DispatchQueue.main.async {
self.avatarImageView.image = image
}
}
}



// MARK: VIEW FUNCTIONS

Expand Down
66 changes: 63 additions & 3 deletions GHFollowers/Managers/NetworkManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ class NetworkManager {

// 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
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
Expand Down Expand Up @@ -160,4 +162,62 @@ class NetworkManager {
task.resume()
}



// MARK: Avatar Download
func downloadImage(from urlString: String, completed: @escaping (UIImage?) -> Void) {

// CHECK IF IMAGE IS CACHED SO WE DONT DOWNLOD AGAIN

// convert urlString to NSString
let cacheKey = NSString(string: urlString)

// cacheKey already cached then return it and dont download
if let image = cache.object(forKey: cacheKey) {
completed(image)
return
}

// else go down here and download the image

// if param is not valid url return
guard let url = URL(string: urlString) else {
completed(nil)
return
}

// make api call
let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in

// combine all guard statements into one
// if all the following are true go ahead and do things
// else completed(nil)
guard let self = self,
// if calls returns error return
error == nil,
//if response exists and is not nil and if status code is 200(OK)
let response = response as? HTTPURLResponse, response.statusCode == 200,
// check if we actually have data returned
let data = data,
// pass the server data to the image
let image = UIImage(data: data) else {
completed(nil)
return
}


// save downloaded image to chache
self.cache.setObject(image, forKey: cacheKey)

// if all ok call completed with image
completed(image)

}

task.resume()
}




}

0 comments on commit c0b7c87

Please sign in to comment.