【iOS】プログラミング素人の俺が、Swift + Firebaseを使って、インスタクローンを作る！【フォロー/フォロワー機能編】

# **目次**
- 前回
- フォロー/フォロワー機能を作る
- Database
- フォローリストボタン&フォロワーリストボタン作成して、画面遷移させる
- フォローボタンを実装する
- フォロー処理
- フォロー解除処理
- 完成
- 感想
- 次回


# **前回**
[【iOS】プログラミング素人の俺が、Swift + Firebaseを使って、インスタクローンを作る！【超簡易検索機能編】](https://qiita.com/umagoro/items/eaf6ac1723bbe4bb4e91)
# **フォロー/フォロワー機能を作る**
さて、いよいよフォロー/フォロワー機能の実装である。
今回の機能は、一番頭を悩ませた。
**ちなみに、アンフォロー(フォロー解除)機能は僕の技術力不足により、今回実装しないことにした。**
(厳密には、アンフォロー自体はできるのだが、**アンフォローしたユーザーの再フォローが不可となってしまうため。(~~たぶん、XcodeかFirebaseのバグだと思う~~)**)

# **Database**
<img width="424" alt="スクリーンショット 2018-03-12 11.28.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/154610/aee88ffe-c4e5-f822-d677-92106c8f7898.png">
Followには、ログインユーザUIDの子キーに検索対象ユーザUID、その値に検索対象ユーザのuserのID番号(userの子キー。bbbの場合は02)を入れた。

# **フォローリストボタン&フォロワーリストボタン作成して、画面遷移させる**
まず、フォローリストボタン&フォロワーリストボタンを作成する。

```swift:AnotherUserViewController.swift

let UserFollowCount = self.ref.child("user/\(FollowUser)/Follow")
UserFollowCount.observe(DataEventType.value, with: { (snapshot) in
   let UserFollowCountStr = snapshot.value as? String
   let UserFollowCountInt = Int(UserFollowCountStr!)
   //フォローボタン
   let FollowPage = UIButton(frame: CGRect(x: w7 - 130, y: 50, width: 130, height: 30))
   FollowPage.backgroundColor = . black
   FollowPage.setTitle("フォロー \(UserFollowCountInt!)", for: UIControlState())
   FollowPage.addTarget(self, action: #selector(AnotherUserViewController.Followpage(_:)), for: .touchUpInside)
   self.scView.addSubview(FollowPage)
})
                                            
let UserFollowerCount = self.ref.child("user/\(FollowUser)/Follower")
UserFollowerCount.observe(DataEventType.value, with: { (snapshot) in
   let UserFollowerCountStr = snapshot.value as? String
   let UserFollowerCountInt = Int(UserFollowerCountStr!)
   //フォロワーボタン
   let FollowerPage = UIButton(frame: CGRect(x: w7 - 130, y: 100, width: 130, height: 30))
   FollowerPage.backgroundColor = . black
   FollowerPage.setTitle("フォロワー \(UserFollowerCountInt!)", for: UIControlState())
   FollowerPage.addTarget(self, action: #selector(AnotherUserViewController.Followerpage(_:)), for: .touchUpInside)
   self.scView.addSubview(FollowerPage)
})

```
まず、検索対象ユーザのフォロー数とフォロワー数を取得して、それをUIButtonのsetTitleに反映する。
続いて、画面遷移の処理を行う。

```swift:AnotherUserViewController.swift
    @objc func Followerpage(_: UIButton){
        let vc = FollowerViewController(titleName: "Follower")
        navigationController?.pushViewController(vc, animated: true)
    }
    
    
    @objc func Followpage(_: UIButton){
        let vc = FollowViewController(titleName: "Follow")
        navigationController?.pushViewController(vc, animated: true)
    }
```

```swift:FollowViewController
import UIKit

class FollowViewController: UIViewController {
    //UIScrollView初期設定
    let foView = UIScrollView(frame: CGRect(x: 0 , y: 0, width: w7, height: h7))
    
    let titleName2: String
    
    init(titleName: String) {
        self.titleName2 = titleName
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.title = titleName2
        
        navigationItem.title = "フォロー"
        
        foView.backgroundColor = .white
        foView.isPagingEnabled = false
        
        
        
        view.addSubview(foView)
    }


}

```
これで、反映ができる。
# **フォローボタンを実装する**
今回は、フォローして、データを更新した後、「フォロー中」のラベルを表示する。
先程も言ったが、アンフォロー機能は実装しない。

```swift:AnotherUserViewController.swift
//フォローボタンの表示・非表示
let loginuserName = self.ref.child("user/\(FollowerUser)/username")  //ログインユーザ自身のユーザネームを取得
loginuserName.observe(DataEventType.value, with: { (snapshot) in
  let loguserNameStr = snapshot.value as? String
  //ログインユーザのユーザネームを検索した場合、非表示
  if loguserNameStr! == searchuserStr {
    print("Cannot Following")
  } else {
    var c = 0
    let follower = self.ref.child("Follower/\(imgstr)/\(user.uid)")
    follower.observe(DataEventType.value, with: { (snapshot) in
    let followerStr = snapshot.value as? String
     if followerStr != nil {
      self.FollowBotton.removeFromSuperview()
      self.FollowNow.backgroundColor = .red
      self.FollowNow.text = "フォロー中"
      self.FollowNow.textAlignment = .center
      self.FollowNow.textColor = .white
      self.scView.addSubview(self.FollowNow)
     } else {
      self.FollowNow.removeFromSuperview()
      self.FollowBotton.backgroundColor = .blue
      self.FollowBotton.removeTarget(self, action: #selector(AnotherUserViewController.Follow(_:)), for: .touchUpInside)
      self.FollowBotton.addTarget(self, action: #selector(AnotherUserViewController.Follow(_:)), for: .touchUpInside)
      self.FollowBotton.setTitle("フォロー", for: UIControlState())
      self.scView.addSubview(self.FollowBotton)
    }
   })

                                                    
}

})
```
まず、自分自身を検索した際は、フォローボタンが表示しないようにしている。

そして、フォローした時のデータ更新処理を行う。

```swift
@objc func Follow(_ : UIButton) {
        
        
        FollowerUserUp = Follower + 1
        self.ref.child("Follower").child("\(imgstr)").updateChildValues(["\(self.userID!)": "\(FollowerUser)"])
        self.ref.child("user").child("\(FollowUser)").updateChildValues(["Follower": "\(FollowerUserUp)"])
        
        LoginUserFollowUp = loginUserFollow + 1
        self.ref.child("Follow").child("\(self.userID!)").updateChildValues(["\(imgstr)": "\(FollowUser)"])
        self.ref.child("user").child("\(FollowerUser)").updateChildValues(["Follow": "\(LoginUserFollowUp)"])

        
}
```
# **完成**
**・未フォロー時**

<img width="405" alt="スクリーンショット 2018-03-11 21.04.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/154610/744ff719-98b6-b849-c8fe-2fe5580d55a4.png">

**・フォロー時**

<img width="410" alt="スクリーンショット 2018-03-12 11.51.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/154610/3b338fe0-0550-7572-26c2-d0b20d8ea2fd.png">

**・自分自身を検索した時**

<img width="408" alt="スクリーンショット 2018-03-11 21.04.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/154610/c1af7271-1ec7-fabc-94fa-cd5869c23006.png">


# **アンフォロー(フォロー解除)処理について**
今回、アンフォロー処理を実装しなかったが、
原因はフォロー解除した後に再びフォローすると、
何らかの原因でフォロー処理とアンフォロー処理が同時に呼ばれてしまい、処理が狂ってしまうので実装しませんでした。
なぜそうなるのかは、今だにわからず。。。。。。
色々対策を立てましたが、全然治りませんでした。。。。。。


# **感想**
とりあえず、しばらくインスタクローンはお休みしようかなと。。。。
**Swift + Firebaseでインスタクローンは、かなり無茶なのではないか**と思ってしまったからです。
正直、Databaseが個人的に慣れないです。「SQL文なら！」と思うことが何度あったか・・・。
もし次回やるなら、フォローリスト表示にしようかなと思っていますが、とりあえずしばらくお休みします。


# **次回**
現在のところ、未定