꾸준히 안타치기

클라이언트와 서버에서 좋아요의 처리는? 본문

iOS/문제해결

클라이언트와 서버에서 좋아요의 처리는?

글자줍기 2022. 5. 14. 03:42
반응형

클라이언트와 서버에서 좋아요의 처리를 어떻게 해야할지에 대한 고민

현재 게시글의 좋아요를 누르면 이 정보를 서버로 보내서 테이블에 저장을 하고 있는 상태.(글번호,ID)

좋아요정보를 서버로 보내는 이유는 좋아요를 모아서 보기위함

이때 하트버튼을 토글방식으로 누르고 있는데 ♡(눌리기전) -> ♥(누른후)

처음엔 버튼의 눌리는것의 정보도 함께 서버로 보내서 저장을 하고 그 값을 가져와서

그대로 뿌리는 방법을 생각했는데 단순한 버튼의 눌림은 클라이언트 상에서만 정보를 갖고 있어도 되지 않을까 라는 생각이들었고

은둔 고수님들의 생각은 어떤지 궁금해 카페에 질문을 해보았다. https://cafe.naver.com/mcbugi

생각한 구현방법?!

  • 로그인했을때 아이디값+게시글번호(좋아요 버튼의 눌림 여부)를 UserDefault나 Coredata로 저장해 가지고 있는다.( 앱을 삭제하기 전까지는 정보 유지 ) -> 문제) 서버와 클라이언트에 싱크문제가 발생할수 있다. 좋아요수를 카운트 할수 없다. 클라이언트, 서버에서의 작업을 한번씩 해야하는 번거로움이 있다.
  • 인터넷이 끊겼을때는 하트버튼 자체를 눌리지 않게 한다. 

의견들 

좋아요 상태나 카운트는 당연히 서버에서 관리되어야 하는 것이니, 이걸 아예 보내지 않으면 안된다.
'UI는 유저가 껄끄럽지 않게 즉시 반영, 서버로의 호출은 조금이라도 부하를 줄이는 방식으로' 가 핵심입니다.
눌렀을 때 UI를 선반영, 그리고 응답결과에 따른 후처리를 하는거죠. 그리고 좋아요 연타 시 불필요하게 많은 호출을 막기 위해 약간의 딜레이도 줍니다.(연속으로 막 누르면 UI는 계속 변경하고, 마지막 한번만 서버로 요청)

대부분 ui 선반영 후 비동기로 서버로 보냅니다. 이후 결과(오류, 성공)에 따라서 ui에 다시 반영합니다. 또한 짧은 시간내 연속적으로 호출할 때는 경우에 따라 debouncing 또는 throttling 처리하기도 하고요. 오프라인 모드를 지원하기 위해서 모든데이터를 로컬DB를 거쳐서 서버와 주고 받으며 싱크를 맞추기도 합니다.

라는 고마운 조언들을 해주셔서 결론적으로 굳이 클라이언트에 저장하기보다는  관리를 위해서 서버에 저장하고 가져오는 것이 낫다라는 결론을 내렸다.

마주친 문제1

처음에 서브쿼리를 작성을 하지 못해서 게시글내용을 호출하고 하트눌림여부를 따로 호출해 2번 데이터를 가져오는 방법을 시도했으나

게시글응답과 하트응답의 갱신 처리등이 꼬여서 outofIndex가 발생했다. 스크롤을 할때마다 다시 게시글을 추가로 가져오는데 이 때 

게시글요청1과 하트요청1이  응답시 한쪽이 먼저 응답이 오거나 둘다 와버려서 시기가 안맞아 한쪽만 테이블뷰가 reload되어 outofIndex가 발생하는것....순차적으로 처리를 해야하는것 같았다. 결론은 한방에 가져오는게 제일 깔끔한것 같아서. 눈물을 흘리며 쿼리를 작성했다. 계속 두번씩 요청하는것은 비효율적이지

마주친 문제2

좋아요값을 서버에서 가지고는 왔고, 테이블뷰 커스텀셀을 작성하면서 프로토콜을 작성해 버튼을 눌리게끔했는데 

이때 UI만 눌러져있게 하는 부분이 헷갈려 어디인지 찾느라 고생했다. 커스텀셀 프로토콜과정에 대해서 다시 정리가 필요하다.

좋아요의 눌림여부는 딕셔너리를 만들어서 해당 게시글의 On/Off 여부를 나타낸다.

    //좋아요를 하기위한 딕셔너리
    lazy var likes: [Int:Int] = [:]

테이블뷰셀의 좋아요버튼을 눌렀을때 

  //좋아요 버튼 눌림 상태 
        if likes[indexPath.row] == 1 {
            cell.isTouched = true
            numIdx  = self.feedModel?.results[indexPath.row].feedIdx?.description ?? ""
            
        }else{
            cell.isTouched = false
        }

직접눌렀을때는 버튼이 ON됨과 동시에 서버로 좋아요값을 업로드하는데, 서버에서 데이터를 받아올때는 직접누르는 것이 아니므로

버튼이 눌려있게만  likes[indexPath.row] = 1 로 값을 넣어주었다. 그러면 버튼이 On상태로 표시된다.


해결

서버에 저장하고 가져온다. (좋아요 갯수, On/Off상태)

메인 게시글 피드를 가져올때 서버에 데이터를 요청할때 userID값 추가로 보내고

좋아요 값을 카운트하는 서브쿼리를 추가로 작성하여 좋아요의 값을 함께 가져왔다.

(SELECT count(*) FROM postLike where postIdx = images.feedIdx and userID = '$userID') as cbheart

조회해라 카운트를 postLike(좋아요테테이블)의 게시글번호와 images(게시글테이블)의 게시글번호가 같고, userID가 작성자인 것의 하트수를 / 그리고 그값을 cbheart라는 행을 생성해서 넣어라.

 

클라이언트에서 cbheart값을 받아서

좋아요의 값이 1이상이면 눌림상태를 On으로 유지하도록 하였다.( 버튼 액션X, UI만 On된 상태유지 )

앱을 껐다 켤때 새로 서버에서 데이터를 가져오므로 로그인, 로그아웃시에도 내가 누른 좋아요 상태가 유지 된다. 


반응형
Comments