LoginSignup
11
14

More than 5 years have passed since last update.

【iOS】プログラミング素人の俺が、Swift + Firebaseを使って、インスタクローンを作る!【写真投稿編】

Last updated at Posted at 2018-03-05

目次

  • 前回
  • 写真投稿機能を作る
  • 感想
  • 参考サイト
  • 次回

【2018/03/05更新】

後述の問題点が解消したので、書き直しました。

前回

【iOS】プログラミング素人の俺が、Swift + Firebaseを使って、インスタクローンを作る!①

写真投稿機能を作る

今回は写真投稿機能を作るが、少し複雑なので、システムの全体像から入っていく。

① 具体的なシステム全体像

スクリーンショット 2018-03-05 11.26.59.png

手順としては、
1. 画像をStorageにアップロード&ダウンロードURLをRealTime DataBaseに保存
2. ダウンロードURLを取得
3. Storageからダウンロードする

という感じで。

② RealTime Database

DBの所はまだよくわからない感じだが、とりあえずこのようにした。

スクリーンショット 2018-03-05 20.45.35.png

imagesは、まずユーザーUIDで割り振り、その中にダウンロードURLを格納している。
imgcountは、ユーザーの投稿回数を格納している。
この数値を、imagesの画像IDにしている。

コード

ImageAddViewController.swift
import UIKit
import Firebase
import SDWebImage

//ディスプレイサイズ取得
let w2 = UIScreen.main.bounds.size.width
let h2 = UIScreen.main.bounds.size.height

//カウント設定
var count: String!
//画像表示用ImageView
let imageView = UIImageView(frame: CGRect(x: (w2 - 200) / 2, y: 300, width: 200, height: 200))
class ImageAddViewController: UIViewController {
    //DB参照作成
    var ref: DatabaseReference!
    //ユーザーUID取得
    let userID = Auth.auth().currentUser?.uid
    //アップロードボタン
    let add = UIButton(frame: CGRect(x: (w2 - 150) / 2, y: 150, width: 150, height: 30))
    override func viewDidLoad() {
        //DBインスタンス作成
        ref = Database.database().reference()
        super.viewDidLoad()


        //アップロードボタン設定
        add.backgroundColor = .red
        add.addTarget(self, action: #selector(ImageAddViewController.Imageadd(_:)), for: .touchUpInside)
        add.setTitle("アップロード", for: UIControlState())
        view.addSubview(add)

        //ダウンロードURL取得して、Storageからダウンロードする
        //ログイン情報取得
        let user = Auth.auth().currentUser
        if let user = user {

            //imgcountのカウントデータ値の存在確認
            let imgCount = self.ref.child("imgcount/\(user.uid)/count")
            imgCount.observe(DataEventType.value, with: { (snapshot) in
                let Count = snapshot.value
                var Countstr = Count as? String
                if Countstr == nil {
                    //存在しない場合、新規データ作成(countは0にする)
                    self.ref.child("imgcount").child(self.userID!).setValue(["count": "0"])
                    Countstr = "0"
                } else {
                    //データから呼んだ値をカウントアップして、セットする
                    var CountInt = Int(Countstr!)
                    CountInt! += 1
                    let ud = UserDefaults.standard
                    ud.set(CountInt, forKey: "count")
                    //ダウンロードURLの存在確認
                    let imageURL = self.ref.child("images/\(user.uid)/\(Countstr!)/profile")
                    print(imageURL)
                    imageURL.observe(DataEventType.value, with: { (snapshot) in
                        let url = snapshot.value as? String
                        if url == nil {
                            print("ファイルなし")
                        } else {
                            //ダウンロードURLを取得し、ImageViewに反映
                            let strURL = URL(string: url!)
                            imageView.sd_setImage(with: strURL)
                            self.view.addSubview(imageView)
                        }
                    })
                }

                //imagesのデータの存在確認
                let newUser = self.ref.child("images/\(user.uid)/\(Countstr!)/profile")
                newUser.observe(DataEventType.value, with: { (snapshot) in
                    let profile = snapshot.value as? String
                    if profile == nil  {
                        //データ値がない場合、新規データを作成
                        self.ref = Database.database().reference()
                        self.ref.child("images").updateChildValues(["\(self.userID!)": "userID"])
                        print("新規ユーザー")
                    } else {
                        print("既存")
                    }

                })
          })
        }
    }

    ///アルバム呼び出し
    @objc func Imageadd(_ : UIButton) {
        pickImageFromLibrary()
    }

    //カウンタ
    func countPhoto() -> String {
        let ud = UserDefaults.standard
        let count = ud.object(forKey: "count") as! Int
        ud.set(count + 1, forKey: "count")
        return String(count)
    }

}

//アルバムにアクセス
extension ImageAddViewController: UINavigationControllerDelegate {
    func pickImageFromLibrary() {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
            let controller = UIImagePickerController()
            controller.delegate = self
            controller.sourceType = UIImagePickerControllerSourceType.photoLibrary

            present(controller, animated: true, completion: nil)
        }
    }
}

//Storageに書き込み
extension ImageAddViewController: UIImagePickerControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo
        info: [String : Any]) {
        let storage = Storage.storage()
        let storageRef = storage.reference()
        let user = Auth.auth().currentUser
        if let user = user {
            count = countPhoto()
            if let data = UIImagePNGRepresentation(info[UIImagePickerControllerOriginalImage] as! UIImage) {
                let reference = storageRef.child("image/" + user.uid + "/" + count + ".jpeg")
                let meta = StorageMetadata()
                meta.contentType = "image/jpeg"
                reference.putData(data, metadata: meta, completion: { metaData, error in
                    if (error != nil) {
                        print("Uh-oh, an error occurred!")
                    } else {
                        //URL型をNSstring型に変更
                        let downloadURL = metaData!.downloadURL()

                        let data = downloadURL!.absoluteString
                        self.ref = Database.database().reference()
                        self.ref.child("images").child(self.userID!).child(count).updateChildValues(["profile": data])
                        self.ref.child("imgcount").child(self.userID!).setValue(["count": count])
                        print("成功!")
                    }
                })
                dismiss(animated: true, completion: nil)
            }
        }
    }

}



コードはこんな感じ。
このコードにはまだ問題点があり、

1. ログインする毎に、countが初期化されてしまう(DBも初期値に上書きされてしまう。)
2. 上記の影響で、過去に格納していた画像が上書きされてしまう。
3. 新規ユーザーが最初にログインした場合、画像呼び出しのところで、エラーが起きる。

この問題が解決次第、あげ直しますm(_ _)m

完成品

testgif.gif

感想

とりあえず、問題点は解消したいですね。
それが出来次第、今度は画像をリスト化して、呼び出したいですね。

【追記】
問題点、解消しました。
いやぁ〜、大変だった。。。

参考サイト

[ios]firebase storageを使用して、画像をアップロードしてからRealtime DatabaseにURLを保存するまで
Firebase Storageに画像をアップロードをするサンプルを作ってみた!
FirebaseStorageの画像をSDWebImageで表示しようとして詰まった話

次回

【iOS】プログラミング素人の俺が、Swift + Firebaseを使って、インスタクローンを作る!【画像リスト化編】

11
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
14