1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Swift】使い回しできるコードまとめ

Posted at

xcode 12.4
iOS 14.0
これからSwiftでアプリを作成するにあたり、使い回せそうなコードを自分の都合でまとめました。

ライブラリ

podの準備

pod init

pod 'Firebase'
pod 'Firebase/Auth'
pod 'Firebase/Storage'
pod 'Firebase/Firestore'
pod 'SDWebImage'
pod "ViewAnimator"
pod 'ActiveLabel'

pod install

Firebase/Authを利用したログイン機能の実装(匿名ログイン)

FirebaseでGoogleServise-Info.plistをダウンロードし、ファイル内に配置したら...

AppDelegate.swift
import Firebase

class AppDelegate: UIResponder, UIApplicationDelegate {
//(中略)
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        FirebaseApp.configure() //<- 追加,firebaseauthを使うときに必要
        return true
  }
//(中略)
}

firebase/storageを利用したプロフィール画像設定機能の実装

カメラとアルバムの使用を許可するためのファイルの作成

Model/checkModel.swift
import Foundation
import Photos

class CheckModel {
    
    func showCheckPermission() {
        PHPhotoLibrary.requestAuthorization { (status) in
            switch(status) {
            case .authorized:
                print("許可")
            case .denied:
                print("拒否")
            case .notDetermined:
                print("notDetermined")
            case .restricted:
                print("restricted")
            case .limited:
                print("limited")
            @unknown default: break
            }
        }
    }
}

ログインボタンの実装

Controller/LoginViewController.swift
import UIKit
import Firebase //<-追加
import FirebaseAuth //<-追加

class LoginViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @IBOutlet weak var profileImageView: UIImageView! //<-storyboardと繋げる
    @IBOutlet weak var textField: UITextField! //<-storyboardと繋げる
    
    var sendDBModel = SendDBModel() //<-別途SendDBModelを作成 作成したModelを使用するためにインスタンス化が必要
    
    var urlString = String() //<-クラウドに保存した画像のurlを利用するための箱
    override func viewDidLoad() {
        super.viewDidLoad()

        //許可画面
        let checkModel = CheckModel()
        checkModel.showCheckPermission()
    }
    
    @IBAction func login(_ sender: Any) {
        //匿名ログイン
        Auth.auth().signInAnonymously { (result, error) in
            //データベースのデータがresultに入る
            //エラー処理
            if error != nil {
                return
            }
            //ユーザーが本当にいるのか
            let user = result?.user
            print(user.debugDescription)
            //次の画面遷移 -> 次のViewControllerへ
            let selectVC = self.storyboard?.instantiateViewController(identifier: "selectVC") as! selectRoomViewController
            //アプリ内に名前を保存する forkeyはキー値
            UserDefaults.standard.setValue(self.textField.text, forKey: "userName")
            //画像をクラウドストレージに送信する + データを圧縮する
            let data = self.profileImageView.image?.jpegData(compressionQuality: 0.01)
            //データをストレージに保存する クラス名.sendProfileImageData(data: data)->classのメソッドに入る
            self.sendDBModel.sendProfileImageData(data: data!)
            //画面遷移
            self.navigationController?.pushViewController(selectVC, animated: true)
        }
    }
}

プロフィール画像をFirebaseのDBに保存してアプリ内で使用するためのModel

Model/SendDBModel.swift
import Foundation
import FirebaseStorage

class SendDBModel {
    //送信機能を集約するクラス
    init () {
    }
    func sendProfileImageData(data:Data) {
        let image = UIImage(data:data)
        let profileImage = image!.jpegData(compressionQuality: 0.1)
        
        //保存先の決定
        //リファレンス パスを作り、フォルダを作成している UUIDで一意性のIDを作成し、uuid+dateでデータ名をつけている
        let imageRef = Storage.storage().reference().child("profileImage").child("\(UUID().uuidString + String(Date().timeIntervalSince1970)).jpg")
        //送信作業
        imageRef.putData(profileImage!, metadata: nil) { (metadata, error) in
            if error != nil {
                return
            }
            //firebaseのサーバーから画像のurlが帰ってくる
            imageRef.downloadURL { (url, error) in
                if error != nil {
                    return
                }
                //userImageというキー値で画像を保存
                UserDefaults.standard.setValue(url?.absoluteString, forKey: "userImage")
            }
        }
    }
}

カメラとアルバムを使用するためのメソッド

Controller/LoginViewController.swift
func doCamera() {
        let sourceType:UIImagePickerController.SourceType = .camera
        //カメラ利用可能かチェック
        if UIImagePickerController.isSourceTypeAvailable(.camera){
            let cameraPicker = UIImagePickerController()
            cameraPicker.allowsEditing = true
            cameraPicker.sourceType = sourceType
            cameraPicker.delegate = self
            self.present(cameraPicker, animated: true, completion: nil)
        }
    }
    func doAlbum() {
        let sourceType:UIImagePickerController.SourceType = .photoLibrary
        //アルバム利用可能かチェック
        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
            let cameraPicker = UIImagePickerController()
            cameraPicker.allowsEditing = true
            cameraPicker.sourceType = sourceType
            cameraPicker.delegate = self
            self.present(cameraPicker, animated: true, completion: nil)
        }
    }
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if info[.originalImage] as? UIImage != nil {
            let selectedImage = info[.originalImage] as! UIImage
            profileImageView.image = selectedImage
            picker.dismiss(animated: true, completion: nil)
        }
    }

画像選択部分をタップするとアラートが出現し、カメラかアルバムか選択できるようにする

タップ機能が使用できるように、ImageViewUser Interaction Enabledに☑️をいれる。

Controller/LoginViewController.swift
@IBAction func tapImageView(_ sender: Any) {
        let generater = UINotificationFeedbackGenerator()
        generater.notificationOccurred(.success)
        showAlert()
    }
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
    //アラート
    func showAlert() {
        let alertController = UIAlertController(title: "選択", message: "どちらを使用しますか?", preferredStyle: .actionSheet)
        let action1 = UIAlertAction(title: "カメラ", style: .default) { (alert) in
            self.doCamera()
        }
        let action2 = UIAlertAction(title: "アルバム", style: .default) { (alert) in
            self.doAlbum()
        }
        let action3 = UIAlertAction(title: "キャンセル", style: .cancel)
        
        alertController.addAction(action1)
        alertController.addAction(action2)
        alertController.addAction(action3)
        self.present(alertController, animated: true, completion: nil)
    }
  //画面がタッチされたらキーボードを閉じる
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textField.resignFirstResponder()
    }

# キーボードを出現させたり隠れさせたりする

    override func viewDidLoad() {
        super.viewDidLoad()
        
        //キーボード
        //iphoneが持っている機能としてキーボードが呼ばれるとkeyboardwillshowが呼ばれる
        NotificationCenter.default.addObserver(self, selector: #selector(EditViewController.keyboardWillShow(_ :)), name: UIResponder.keyboardWillShowNotification, object: nil)
        //キーボードが隠れた時
        NotificationCenter.default.addObserver(self, selector: #selector(EditViewController.keyboardWillHide(_ :)), name: UIResponder.keyboardWillHideNotification, object: nil)
        if UserDefaults.standard.object(forKey: "userName") != nil {
            userName = UserDefaults.standard.object(forKey: "userName") as! String
        }
        if UserDefaults.standard.object(forKey: "userImage") != nil {
            userImageString = UserDefaults.standard.object(forKey: "userImage") as! String
        }
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.setNavigationBarHidden(true, animated: true)
    }
    
    @objc func keyboardWillShow(_ notification:NSNotification) {
        let keyboardHeight = ((notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as Any) as AnyObject).cgRectValue.height
        //y座標は左上から始まる
        //スクリーン全体の高さから、キーボードの高さと、テキストフィールドの高さを引いている
        textField.frame.origin.y = screenSize.height - keyboardHeight - textField.frame.height
        sendButton.frame.origin.y = screenSize.height - keyboardHeight - sendButton.frame.height
    }
    @objc func keyboardWillHide(_ notification:NSNotification) {
        textField.frame.origin.y = screenSize.height - textField.frame.height
        sendButton.frame.origin.y = screenSize.height - sendButton.frame.height
        //キーボードが下がっていく時間がduration
        //durationを渡してanimationを作成する
        guard let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else {return}
        UIView.animate(withDuration: duration) {
            let transform = CGAffineTransform(translationX: 0, y: 0)
            self.view.transform = transform
        }
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textField.resignFirstResponder()
    }
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
1
4
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
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?