From 9f4976a4745d49602f014376564bb08343873053 Mon Sep 17 00:00:00 2001 From: karen Date: Sat, 31 Jul 2021 00:34:47 -0500 Subject: [PATCH 1/7] Asignacion de propiedad liked para decodificar ese campo con base al json de la API --- Secretly/Models/Post.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Secretly/Models/Post.swift b/Secretly/Models/Post.swift index eba5ff0..f1169e2 100644 --- a/Secretly/Models/Post.swift +++ b/Secretly/Models/Post.swift @@ -21,8 +21,9 @@ struct Post: Restable { let longitude: Double? let createdAt: Date? let updatedAt: Date? + let liked: Bool? - init(content: String, backgroundColor: String, latitude: Double? = nil, longitude: Double? = nil, image: UIImage? = nil) { + init(content: String, backgroundColor: String, latitude: Double? = nil, longitude: Double? = nil, image: UIImage? = nil, liked:Bool? = nil) { self.content = content self.backgroundColor = backgroundColor self.id = nil @@ -34,6 +35,8 @@ struct Post: Restable { self.commentsCount = nil self.createdAt = nil self.updatedAt = nil + self.liked = nil + } func encode(to encoder: Encoder) throws { From 11ef59d64a6e4298ca5aec2c0aefa79f4a647da5 Mon Sep 17 00:00:00 2001 From: karen Date: Fri, 6 Aug 2021 19:42:31 -0500 Subject: [PATCH 2/7] =?UTF-8?q?Creaci=C3=B3n=20de=20una=20estructura=20bas?= =?UTF-8?q?ado=20en=20json=20de=20la=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Secretly/Models/Like.swift | 17 +++++++++++++++++ Secretly/Services/LikeService.swift | 9 +++++++++ Secretly/Services/LikeServices.swift | 9 +++++++++ 3 files changed, 35 insertions(+) create mode 100644 Secretly/Models/Like.swift create mode 100644 Secretly/Services/LikeService.swift create mode 100644 Secretly/Services/LikeServices.swift diff --git a/Secretly/Models/Like.swift b/Secretly/Models/Like.swift new file mode 100644 index 0000000..9cbcd90 --- /dev/null +++ b/Secretly/Models/Like.swift @@ -0,0 +1,17 @@ +// +// Like.swift +// Secretly +// +// Created by mac on 31/07/21. +// Copyright © 2021 3zcurdia. All rights reserved. +// + +import Foundation + +struct Like: Restable { + var id : Int? + let createdAt : Date + let updateAt : Date + let user : User +} + diff --git a/Secretly/Services/LikeService.swift b/Secretly/Services/LikeService.swift new file mode 100644 index 0000000..8feb047 --- /dev/null +++ b/Secretly/Services/LikeService.swift @@ -0,0 +1,9 @@ +// +// LikeService.swift +// Secretly +// +// Created by mac on 31/07/21. +// Copyright © 2021 3zcurdia. All rights reserved. +// + +import Foundation diff --git a/Secretly/Services/LikeServices.swift b/Secretly/Services/LikeServices.swift new file mode 100644 index 0000000..98791ed --- /dev/null +++ b/Secretly/Services/LikeServices.swift @@ -0,0 +1,9 @@ +// +// LikeServices.swift +// Secretly +// +// Created by mac on 31/07/21. +// Copyright © 2021 3zcurdia. All rights reserved. +// + +import Foundation From e196872b320a7a4d35382a81fb2e26063f8a5244 Mon Sep 17 00:00:00 2001 From: karen Date: Fri, 6 Aug 2021 19:46:09 -0500 Subject: [PATCH 3/7] =?UTF-8?q?Creaci=C3=B3n=20del=20un=20protoclo=20llama?= =?UTF-8?q?do=20LikeInputDelegate=20con=20las=20funciones=20dislike=20y=20?= =?UTF-8?q?dislike?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FeedCollectionViewController.swift | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/Secretly/ViewControllers/FeedCollectionViewController.swift b/Secretly/ViewControllers/FeedCollectionViewController.swift index 9180d42..4da1d7f 100644 --- a/Secretly/ViewControllers/FeedCollectionViewController.swift +++ b/Secretly/ViewControllers/FeedCollectionViewController.swift @@ -11,6 +11,7 @@ import CoreLocation class FeedCollectionViewController: UIViewController { let feedService = FeedService() + let likeService = LikeService() var posts: [Post]? { didSet { self.collectionView.reloadData() @@ -37,13 +38,16 @@ class FeedCollectionViewController: UIViewController { let nib = UINib(nibName: String(describing: PostCollectionViewCell.self), bundle: nil) collectionView.register(nib, forCellWithReuseIdentifier: PostCollectionViewCell.reuseIdentifier) collectionView.addSubview(refreshControl) - refreshControl.addTarget(self, action: #selector(self.loadPosts), for: UIControl.Event.valueChanged) } @objc func loadPosts() { - feedService.load { [unowned self] posts in self.posts = posts } + feedService.load { [unowned self] posts in + self.posts = posts + + } + } @IBAction @@ -57,5 +61,31 @@ extension FeedCollectionViewController: PostInputViewDelegate { func didCreatePost(post: Post?) { guard let upost = post else { return } self.posts?.insert(upost, at: 0) + + } +} + +protocol LikeInputDelegate{ + func likeToPost(postId: Int) + func dislikeToPost(postId: Int) +} + +extension FeedCollectionViewController : LikeInputDelegate { + + func dislikeToPost(postId: Int) { + guard let posts = self.posts else { return } + let postIndex = posts.firstIndex(where: { $0.id == postId }) + guard let index = postIndex else { return } + likeService.deleteLike(postId: postId) + self.posts?[index].liked? = false + } + + func likeToPost(postId: Int ) { + guard let posts = self.posts else { return } + let postIndex = posts.firstIndex(where: { $0.id == postId }) + guard let index = postIndex else { return } + likeService.createLike(postId: postId) + self.posts?[index].liked? = true + } } From 1ad49bc790f85cf20f1f8c510d8d3d58d6cf3d85 Mon Sep 17 00:00:00 2001 From: karen Date: Fri, 6 Aug 2021 19:52:54 -0500 Subject: [PATCH 4/7] =?UTF-8?q?Creaci=C3=B3n=20de=20la=20extensi=C3=B3n=20?= =?UTF-8?q?basado=20en=20el=20protocolo=20implementado=20para=20obtener=20?= =?UTF-8?q?cuando=20se=20da=20un=20like=20(true=20o=20flase)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Secretly.xcodeproj/project.pbxproj | 8 +++ Secretly/Base.lproj/LaunchScreen.storyboard | 4 +- Secretly/Models/Post.swift | 2 +- Secretly/Network/RestClient.swift | 15 +++- Secretly/Services/LikeServices.swift | 32 ++++++--- ...ntroller+UICollectionViewDataSource .swift | 1 + Secretly/Views/PostCollectionViewCell.swift | 68 ++++++++++++++++--- 7 files changed, 109 insertions(+), 21 deletions(-) diff --git a/Secretly.xcodeproj/project.pbxproj b/Secretly.xcodeproj/project.pbxproj index 8dd4829..9fd4fc9 100644 --- a/Secretly.xcodeproj/project.pbxproj +++ b/Secretly.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 04B404D526B6215B00B1E1FE /* LikeServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04B404D426B6215B00B1E1FE /* LikeServices.swift */; }; + 04B404DF26B7851100B1E1FE /* Like.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04B404DE26B7851100B1E1FE /* Like.swift */; }; 302B5845267E658E007133E6 /* HttpResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302B583D267E658E007133E6 /* HttpResponse.swift */; }; 302B5846267E658E007133E6 /* AmacaConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302B583E267E658E007133E6 /* AmacaConfig.swift */; }; 302B5847267E658E007133E6 /* StatusCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302B583F267E658E007133E6 /* StatusCode.swift */; }; @@ -76,6 +78,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 04B404D426B6215B00B1E1FE /* LikeServices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LikeServices.swift; sourceTree = ""; }; + 04B404DE26B7851100B1E1FE /* Like.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Like.swift; sourceTree = ""; }; 302B583D267E658E007133E6 /* HttpResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HttpResponse.swift; sourceTree = ""; }; 302B583E267E658E007133E6 /* AmacaConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AmacaConfig.swift; sourceTree = ""; }; 302B583F267E658E007133E6 /* StatusCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusCode.swift; sourceTree = ""; }; @@ -222,6 +226,7 @@ 30C77CAF266AD69700A888DC /* CurrentUserService.swift */, 304E06C726742BDA00A99128 /* CreatePostService.swift */, 304E06C926742CC500A99128 /* FeedService.swift */, + 04B404D426B6215B00B1E1FE /* LikeServices.swift */, ); path = Services; sourceTree = ""; @@ -248,6 +253,7 @@ 307A30572661AD540020DF8B /* User.swift */, 30C77CB3266AF47300A888DC /* Credentials.swift */, 30C77CB5266AF48300A888DC /* CurrentUser.swift */, + 04B404DE26B7851100B1E1FE /* Like.swift */, ); path = Models; sourceTree = ""; @@ -453,9 +459,11 @@ 307A305E2661CD510020DF8B /* PostCollectionViewCell.swift in Sources */, 302BB626267E447900FD74F5 /* PostInputViewController+UITextFieldDelegate.swift in Sources */, 30BC8BA02662B8A700F7E6A5 /* StorageType.swift in Sources */, + 04B404DF26B7851100B1E1FE /* Like.swift in Sources */, 307A305B2661B7A20020DF8B /* FeedCollectionViewController.swift in Sources */, 304E06CC2674442800A99128 /* UIImage+encodeBase64.swift in Sources */, 30BC8BA62662C02300F7E6A5 /* CacheImage.swift in Sources */, + 04B404D526B6215B00B1E1FE /* LikeServices.swift in Sources */, 302B5847267E658E007133E6 /* StatusCode.swift in Sources */, 302B584B267E658E007133E6 /* RequestBuilder.swift in Sources */, 307A306526629B990020DF8B /* AuthorView.swift in Sources */, diff --git a/Secretly/Base.lproj/LaunchScreen.storyboard b/Secretly/Base.lproj/LaunchScreen.storyboard index 4d082d6..006a0a1 100644 --- a/Secretly/Base.lproj/LaunchScreen.storyboard +++ b/Secretly/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,8 @@ - + - + diff --git a/Secretly/Models/Post.swift b/Secretly/Models/Post.swift index f1169e2..aa76ab5 100644 --- a/Secretly/Models/Post.swift +++ b/Secretly/Models/Post.swift @@ -21,7 +21,7 @@ struct Post: Restable { let longitude: Double? let createdAt: Date? let updatedAt: Date? - let liked: Bool? + var liked: Bool? init(content: String, backgroundColor: String, latitude: Double? = nil, longitude: Double? = nil, image: UIImage? = nil, liked:Bool? = nil) { self.content = content diff --git a/Secretly/Network/RestClient.swift b/Secretly/Network/RestClient.swift index 3048ccf..1c34a9c 100644 --- a/Secretly/Network/RestClient.swift +++ b/Secretly/Network/RestClient.swift @@ -58,7 +58,20 @@ struct RestClient { complete(newResult) } } - + func delete(_ identifier: String, complete: @escaping (Result) -> Void) { + client.delete(path: "\(path)/\(identifier)") { result in + let newResult = result.flatMap { parse(data: $0) } + complete(newResult) + } + } + + func createNoModel(_ identifier:String, complete: @escaping (Result) -> Void){ + client.post(path: path, body: nil){ result in + let newResult = result.flatMap { parse(data: $0) } + complete(newResult) + } + } + func update(model: T, complete: @escaping (Result) -> Void) throws { let data = try encoder.encode(model) client.put(path: "\(path)/\(model.id)", body: data) { result in diff --git a/Secretly/Services/LikeServices.swift b/Secretly/Services/LikeServices.swift index 98791ed..0570453 100644 --- a/Secretly/Services/LikeServices.swift +++ b/Secretly/Services/LikeServices.swift @@ -1,9 +1,25 @@ -// -// LikeServices.swift -// Secretly -// -// Created by mac on 31/07/21. -// Copyright © 2021 3zcurdia. All rights reserved. -// - import Foundation +struct LikeService { + private var endpoint: RestClient + + init() { + endpoint = RestClient(client: AmacaConfig.shared.httpClient, path: "/api/v1/posts") + } + + func createLike(postId:Int, completion: ((Result) -> Void)? = nil ) { + let identifier = "\(postId)/likes" + endpoint.createNoModel(identifier){ + result in + completion?(result) + } + } + func deleteLike(postId:Int, completion: ((Result) -> Void)? = nil ) { + let identifier = "\(postId)/likes" + endpoint.delete(identifier){ + result in + completion?(result) + } + } + + } + diff --git a/Secretly/ViewControllers/FeedCollectionViewController+UICollectionViewDataSource .swift b/Secretly/ViewControllers/FeedCollectionViewController+UICollectionViewDataSource .swift index 15100dd..36293db 100644 --- a/Secretly/ViewControllers/FeedCollectionViewController+UICollectionViewDataSource .swift +++ b/Secretly/ViewControllers/FeedCollectionViewController+UICollectionViewDataSource .swift @@ -21,6 +21,7 @@ extension FeedCollectionViewController: UICollectionViewDataSource { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PostCollectionViewCell.reuseIdentifier, for: indexPath) as! PostCollectionViewCell cell.post = self.posts?[indexPath.row] + cell.likeDelegate = self return cell } } diff --git a/Secretly/Views/PostCollectionViewCell.swift b/Secretly/Views/PostCollectionViewCell.swift index ee08d53..9d77987 100644 --- a/Secretly/Views/PostCollectionViewCell.swift +++ b/Secretly/Views/PostCollectionViewCell.swift @@ -10,6 +10,7 @@ import UIKit class PostCollectionViewCell: UICollectionViewCell { static let reuseIdentifier = "feedPostCell" + var likeDelegate : LikeInputDelegate? var post: Post? { didSet { updateView() @@ -21,21 +22,70 @@ class PostCollectionViewCell: UICollectionViewCell { @IBOutlet weak var likeState: UIImageView! @IBOutlet weak var commentCounter: UILabel! + override func awakeFromNib() { super.awakeFromNib() + let tap = UITapGestureRecognizer(target: self, action: #selector(likeStateTapped)) + likeState.isUserInteractionEnabled = true + likeState.addGestureRecognizer(tap) } func updateView() { - imageView.image = nil - guard let post = post else { return } - if let color = UIColor(hex: post.backgroundColor) { - self.backgroundColor = color + imageView.image = nil + guard let post = post else { return } + if let color = UIColor(hex: post.backgroundColor) { + self.backgroundColor = color + } + + if let liked = post.liked{ + self.changeLikeState(liked: liked) + } + + self.contentLabel.text = post.content + self.commentCounter.text = String(describing: post.commentsCount ?? 0) + if let postImg = post.image { + ImageLoader.load(postImg.mediumUrl) { img in self.imageView.image = img } + } + self.authorView.author = post.user + + + } + + @objc func likeStateTapped(tapGestureRecognizer: UITapGestureRecognizer){ + print("tocando") + guard let delegate = likeDelegate else {return} + guard let liked = self.post?.liked else {return} + guard let postId = self.post?.id else {return} + if !liked { + delegate.likeToPost(postId: postId) + } else { + delegate.dislikeToPost(postId: postId) } - self.contentLabel.text = post.content - self.commentCounter.text = String(describing: post.commentsCount ?? 0) - if let postImg = post.image { - ImageLoader.load(postImg.mediumUrl) { img in self.imageView.image = img } + } + + func changeLikeState(liked:Bool){ + if liked { + likeState.image = UIImage(systemName:"heart.fill") + likeState.tintColor = .red + } else { + likeState.image = UIImage(systemName:"heart") + likeState.tintColor = .white } - self.authorView.author = post.user } + } + + + + + + + + + + + + + + + From 4452948371ce13853d76731bc3fa4457039de074 Mon Sep 17 00:00:00 2001 From: karen Date: Fri, 6 Aug 2021 19:57:01 -0500 Subject: [PATCH 5/7] Se obtiene el tap(manera programatica) al tocar el corazon para el like y se pinta de color rojo o blanco si el tap es true o false --- Secretly/Views/PostCollectionViewCell.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Secretly/Views/PostCollectionViewCell.swift b/Secretly/Views/PostCollectionViewCell.swift index 9d77987..8d4b86e 100644 --- a/Secretly/Views/PostCollectionViewCell.swift +++ b/Secretly/Views/PostCollectionViewCell.swift @@ -50,7 +50,7 @@ class PostCollectionViewCell: UICollectionViewCell { } - + //captura el tap @objc func likeStateTapped(tapGestureRecognizer: UITapGestureRecognizer){ print("tocando") guard let delegate = likeDelegate else {return} From 464b47c1e046bb6ea1854c2a41d0070b18b237d4 Mon Sep 17 00:00:00 2001 From: karen Date: Fri, 6 Aug 2021 19:58:43 -0500 Subject: [PATCH 6/7] =?UTF-8?q?Se=20a=C3=B1adi=20la=20variable=20liked=20d?= =?UTF-8?q?el=20tipo=20bool=20en=20la=20estructura=20Post=20y=20se=20inici?= =?UTF-8?q?alizo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Secretly/Models/Post.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Secretly/Models/Post.swift b/Secretly/Models/Post.swift index aa76ab5..1f92e94 100644 --- a/Secretly/Models/Post.swift +++ b/Secretly/Models/Post.swift @@ -9,6 +9,7 @@ import Foundation import UIKit + struct Post: Restable { var id: Int? let content: String From 207a6c183938e217345b966de9e8f1c223d43f03 Mon Sep 17 00:00:00 2001 From: karen Date: Fri, 6 Aug 2021 20:03:45 -0500 Subject: [PATCH 7/7] Se implemento un servicio con las funciones de createLike y deleteLike para obtener el identificador y poder crear o borrar el like --- Secretly/Services/LikeServices.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Secretly/Services/LikeServices.swift b/Secretly/Services/LikeServices.swift index 0570453..efffd43 100644 --- a/Secretly/Services/LikeServices.swift +++ b/Secretly/Services/LikeServices.swift @@ -1,11 +1,10 @@ import Foundation + struct LikeService { private var endpoint: RestClient - init() { endpoint = RestClient(client: AmacaConfig.shared.httpClient, path: "/api/v1/posts") } - func createLike(postId:Int, completion: ((Result) -> Void)? = nil ) { let identifier = "\(postId)/likes" endpoint.createNoModel(identifier){ @@ -21,5 +20,5 @@ struct LikeService { } } - } +}