20210113のSwiftに関する記事は6件です。

【Swift】CollectionViewを使用してみる

はじめに

最近Swiftの学習をはじめました。学習の一環としてちょっとしたものを開発しています。
開発にあたり、CollectionViewを初めて使用したのでこちらについて学んだことをまとめていきます。

開発環境

  • macOS Catalina version10.15.7
  • Xcode version12.2
  • Swift5

そもそもCollectionViewとは?

CollectionViewとは、下記画像のように多くのアイテムをパネルのように一覧として表示させたい時に使われるものです。

※参考画像
スクリーンショット 2021-01-12 23.24.59.png

実際に使ってみよう

まずはCollectionViewを設置する

スクリーンショット 2021-01-12 23.11.51.png

設置した後は、セルのIdentifierの設定をする。
今回は、cellとする。
スクリーンショット 2021-01-12 23.22.37.png


UILabelの設置

セル上にLabelを設置します。設置した後にLabelのTagを設定する。Tagを設定することで各セルのUI部品にアクセスできるようになります。
スクリーンショット 2021-01-12 23.40.34.png


UICollectionViewDelegateとUICollectionViewDataSourceを追加する

CollectionViewを使用するにあたり、UICollectionViewDelegateUICollectionViewDataSourceを追加する。

また追加した際に、実装する必要のあるメソッドを追加します。(Fixを押すと補完してくれます)
スクリーンショット 2021-01-13 21.29.04.png

//セクションの中のセルの数を返す
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    //今回はとりあえず12とする。(配列に表示させたいデータを入れている場合は配列のデータ数を返せば良い。)
    return 12
}
//セルに表示する内容を記載する
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    //storyboard上のセルを生成 storyboardのIdentifierで付けたものをここで設定する
    let cell:UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)

    //セル上のTag(1)とつけたUILabelを生成
    let label = cell.contentView.viewWithTag(1) as! UILabel

    //今回は簡易的にセルの番号をラベルのテキストに反映させる
    label.text = String(indexPath.row + 1)

    return cell
}

ViewControllerとCollectionViewを紐付けする

storyboardのviewControllerの階層が表示されている部分で、CollectionViewを右クリックしながらViewControllerにdataSourcedelegateを紐付けする。
※これを忘れるとセルは表示されないので注意!

スクリーンショット 2021-01-13 21.55.26.png

ここまでで下記画像のように最低限セルが表示されます。
(セルの背景色を変更することでわかりやすく確認できます。また、ラベルの位置を調整しないとセル上にうまく表示されません)

スクリーンショット 2021-01-12 23.24.59.png

ビルドする際に、自分は以下のエラーにひっかかり少し苦戦しました。

Could not cast value of type 'UIView' to 'UILabel'

原因を調べてみたところ、どうやらTagをつける箇所を間違えていました。上記の通りLabelにTagを設定できていれば大丈夫ですが、間違えてContentView部分にTagを設定してしまったためこちらのエラーが出たのかなと思います。
Tagを設定する際は、しっかりと確認してから設定しましょう。

セルのサイズを変更したい!

今のままではセルのサイズが小さいのでサイズを変更したい!
そんなときは、UICollectionViewDelegateFlowLayoutを使用することでセルを調整(セルのサイズ調整、セル間の距離調整)できます。

スクリーンショット 2021-01-13 22.22.19.png

セルのサイズを指定する処理はこちらのメソッドを使用する。

//セルのサイズを指定する処理
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    // 横方向のスペース調整
    let horizontalSpace:CGFloat = 5

    //セルのサイズを指定。画面上にセルを3つ表示させたいのであれば、デバイスの横幅を3分割した横幅 - セル間のスペース*2(セル間のスペースが二つあるため)
    let cellSize:CGFloat = self.view.bounds.width/3 - horizontalSpace*2

    // 正方形で返すためにwidth,heightを同じにする
    return CGSize(width: cellSize, height: cellSize)
}

スクリーンショット 2021-01-12 23.24.59.png

一行にセルを2つ表示させたい場合は、下記のように変えるとできます。
(行間の数が1つになる点注意)

et cellSize:CGFloat = self.view.bounds.width/2 - horizontalSpace

セルをタップした際に、画面遷移させたい!

そんな時は、didSelectItemAtメソッドを使用することで実装できます。
(遷移先のViewControllerにセグウェイをつなげている前提)

//セル選択時の処理
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    //指定の遷移先に遷移する(最低限の処理)     
    performSegue(withIdentifier: "指定のIdentifier", sender: nil)
}

まとめ

今回はCollectionViewを初めて使用したので、簡単にまとめてみました。
正直まだしっかりと理解はできていないので、引き続き学習を進めていきます!

Swiftの勉強をするようになり、普段使っているアプリはどうやって作られているか意識するようになりとても勉強になります。いつか、開発したアプリをAppStoreに公開して他の人に使ってもらえるよう引き続き手を動かしていろいろ作ってみます。

以上。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】FirebaseUIを使ったTwitterログイン機能の実装方法③

本記事は、
【Swift】FirebaseUIを使ったTwitterログイン機能の実装方法②の続きになります。

【Swift】FirebaseUIを使ったTwitterログイン機能の実装方法①では、
完成形やコードの全容を紹介しています。

実装方法については、本記事と
【Swift】FirebaseUIを使ったTwitterログイン機能の実装方法②をご覧ください。

実装方法の続きに参ります。

Firebaseとアプリの連携

前回の記事でダウンロードしたファイルをアプリ内に持っていきます。
GoogleService-Info.plistというファイルです。
スクリーンショット 2021-01-13 8.09.46.png
先ほどのGoogleService-Info.plistファイル内にある、
REVERSED_CLIENT_IDのvalue(com.から始まる文字列)をコピーします。

コピー後、プロジェクト > Info > URL Typeを開き、+を押します。
すると画像のように項目が追加されるので、URL Schemesに先ほどの内容を貼り付けます。
スクリーンショット 2021-01-13 8.14.06.png

CocoaPodsでFirebaseUIをインストールする

ターミナルを開き、cdコマンドでディレクトリを移動します。

私の場合は下記のような感じです。

$ cd Desktop/project/SampleTwitterLogin/

Podfileの生成を行います。

$ pod init

Podfireを編集します。

$ vi Podfile

iキーを押し編集モードにし、下記を追加します。

pod 'Firebase/Core'
pod 'FirebaseUI'

追加したら次のような状態になっているはずです。
(バージョンにより多少異なる可能性があります。)

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'SampleTwitterLogin' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for SampleTwitterLogin
   pod 'Firebase/Core'   // 追加
   pod 'FirebaseUI'   // 追加

end

escキーを押して編集モードを解除し、
:wqの3つのキーを押してファイルを保存します。

次にインストールを行います。

$ pod install

エラーが出なければインストール完了です。

アプリ内でログイン機能の実装

Podをインストールしたので、XCodeを開きなおします。
(拡張子が.xcworkspaceのファイルを開きます。)

はじめにアプリでFirebaseを初期化します。

AppDelegate.swift
import Firebase

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    FirebaseApp.configure()   // 追加
    return true
}

次にログイン機能の実装を行います。

ログイン機能を実装するために
FirebaseUIFirebaseをimportします。

ViewController.swift
import Firebase
import FirebaseUI

次に、authUIにデフォルトのUIをインスタンス化します。(合っているか自身ないです・・・)
それと、サポートするログイン方法を使用するように FirebaseUI を構成します。

また、画面読み込み時にcheckLoggedIn()を呼び出すようにしています。
checkLoggedIn( )については後ほど説明します。

ViewController.swift
let authUI = FUIAuth.defaultAuthUI()
let providers: [FUIAuthProvider] = [
    FUIOAuth.twitterAuthProvider()
]

override func viewDidLoad() {
    super.viewDidLoad()

    authUI!.delegate = self
    authUI!.providers = providers

    checkLoggedIn()    
}

authUI!.delegate = selfでエラーが出るのでFIXします。
(FUIAuthDelegateプロトコルに準拠していないためエラーが出ます。)

下記のようにプロトコルが追加されるはずです。

ViewController.swift
class ViewController: UIViewController, FUIAuthDelegate { }

viewDidLoadで呼ばれるcheckLoggedIn( )ですが、
ユーザが追加されているかどうかをチェックします。

Auth.auth().addStateDidChangeListener{ }
ユーザが存在した場合はuserに情報を格納します。

存在しない場合はnilが返されるので、
self.login()が実行されます。

ViewController.swift
func checkLoggedIn() {

    Auth.auth().addStateDidChangeListener{auth, user in
        if user != nil{
            print("success")
        } else {
            print("fail")
            self.login()
        }
    }
}

login( )では画面遷移の処理を行います。

let authViewController = authUI!.authViewController()
定数authViewControllerにViewの情報を代入しています。

その後のpresent( )で画面遷移を行っています。

ViewController.swift
func login() {
    let authViewController = authUI!.authViewController()
    self.present(authViewController, animated: true, completion: nil)
}

さいごに

一応これでログインの機能は実装することが出来ます。

しかし、ログイン画面が英語で合ったり、フルスクリーンでなかったりと、
カスタムしないと少し使い勝手が悪いかなと思いました。

一応、実装方法①〜③を順番に行えばTwitterログインを実装出来るはずです!

バージョンの違いにより画面の状態やコードの違いなどが出てくるかもしれませんので、
その時は自分で調べて実装してみてください!

かなり長くなってしまいましたが最後までご覧いただきありがとうございました。

参考

FirebaseUI で iOS アプリに簡単にログインを追加する
Twitter loginを実装

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】FirebaseUIを使ったTwitterログイン機能の実装方法②

本記事は、
【Swift】FirebaseUIを使ったTwitterログイン機能の実装方法①の続きになります。
①では、完成形やコードの全容について記載しております。

実装手順については、本記事をご覧ください。

実装方法

実装方法について一から説明していきます。
バージョンの違いにより多少画面が異なる可能性がありますのでご了承ください。

また、Firebaseとアプリの連携は別記事でまとめていますのでそちらをご覧ください。
-> Firebaseとアプリの連携手順

本記事は、そちらの記事を終了している前提で記載しています。

Firebaseのプロジェクト作成

Firebaseコンソールを開きます。
構築 > Authenticationを選択し、始めるをクリックします。
スクリーンショット 2021-01-13 7.17.21.png
クリックすると次のような画面になります。
スクリーンショット 2021-01-13 7.17.33.png
Twitterをクリックすると、次の画面が出てきますので、
有効にするにチェックを入れてTwitterログインを有効にします。
(APIキーとAPIシークレットは後ほど入力します。)
スクリーンショット 2021-01-13 7.20.03.png

Twitter Developersでアプリの作成

Twitter DeveloperにログインしOverviewをクリックし下にスクロールします。
すると+ Create Appボタンがあると思うのでそちらをクリックします。
スクリーンショット 2021-01-13 6.49.43.png
適当な名前を指定し作成します。
(名前が被っていると作成できません。)
スクリーンショット 2021-01-13 7.27.38.png

FirebaseとTwitter Developersの連携

作成出来ると次の画面に移動すると思います。
コチラのAPI keyAPI secret keyを先ほどのFirebaseにコピペします。
スクリーンショット 2021-01-13 7.28.45.png
それぞれ該当する箇所にコピペしてください。
スクリーンショット 2021-01-13 7.30.28.png
Twitter Developersの方に戻り、App settingsをクリックします。
スクリーンショット 2021-01-13 7.31.28.png
Authentication settingEditをクリックします。
スクリーンショット 2021-01-13 7.32.53.png
Enable 3-legged OAuthを有効にします。
スクリーンショット 2021-01-13 7.42.46.png
Callback URLsWebsite URLを入力します。

Callback URLsには、先ほどのFirebaseのAPI keyやAPI secret keyを入力した箇所の下に
https://から始まるURLが記載されているのでそちらをコピペします。

Website URLには、自分のWebサイトのURLを入力します。
私は、はてなブログのURLを入力しましたが、そんなものない!という方は、
ペライチというサイトで適当に作成しそちらのURLを貼ってください。
スクリーンショット 2021-01-13 7.44.31.png
入力後saveをクリックします。
3-legged OAuth is enabledとなっていればOKです!
スクリーンショット 2021-01-13 7.49.47.png

アプリ内でログイン機能の実装

次にログイン機能の実装を行います。

ログイン機能を実装するために
FirebaseUIFirebaseをimportします。

ViewController.swift
import Firebase
import FirebaseUI

次に、authUIにデフォルトのUIをインスタンス化します。
それと、サポートするログイン方法を使用するように FirebaseUI を構成します。

また、画面読み込み時にcheckLoggedIn()を呼び出すようにしています。
checkLoggedIn( )については後ほど説明します。

ViewController.swift
let authUI = FUIAuth.defaultAuthUI()
let providers: [FUIAuthProvider] = [
    FUIOAuth.twitterAuthProvider()
]

override func viewDidLoad() {
    super.viewDidLoad()

    authUI!.delegate = self
    authUI!.providers = providers

    checkLoggedIn()    
}

authUI!.delegate = selfでエラーが出るのでFIXします。
(FUIAuthDelegateプロトコルに準拠していないためエラーが出ます。)

下記のようにプロトコルが追加されるはずです。

ViewController.swift
class ViewController: UIViewController, FUIAuthDelegate { }

viewDidLoadで呼ばれるcheckLoggedIn( )ですが、
ユーザが追加されているかどうかをチェックします。

Auth.auth().addStateDidChangeListener{ }
ユーザが存在した場合はuserに情報を格納します。

存在しない場合はnilが返されるので、
self.login()が実行されます。

ViewController.swift
func checkLoggedIn() {

    Auth.auth().addStateDidChangeListener{auth, user in
        if user != nil{
            print("success")
        } else {
            print("fail")
            self.login()
        }
    }
}

login( )では画面遷移の処理を行います。

let authViewController = authUI!.authViewController()
定数authViewControllerにViewの情報を代入しています。

その後のpresent( )で画面遷移を行っています。

ViewController.swift
func login() {
    let authViewController = authUI!.authViewController()
    self.present(authViewController, animated: true, completion: nil)
}

さいごに

一応これでログインの機能は実装することが出来ます。

しかし、ログイン画面が英語で合ったり、フルスクリーンでなかったりと、
カスタムしないと少し使い勝手が悪いかなと思いました。

一応、Firebaseとアプリの連携と
実装方法①〜②を順番に行えばTwitterログインを実装出来るはずです!

バージョンの違いにより画面の状態やコードの違いなどが出てくるかもしれませんので、
その時は自分で調べて実装してみてください!

かなり長くなってしまいましたが最後までご覧いただきありがとうございました。

参考

FirebaseUI で iOS アプリに簡単にログインを追加する
Twitter loginを実装
Firebaseとアプリの連携手順

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】FirebaseUIを使ったTwitterログイン機能の実装方法①

はじめに

個人アプリ作成時にFirebaseUIを使ったTwitterログイン機能を実装したので、
備忘録がてらコマンドの共有をさせていただきます。

また、長すぎて一つの記事に全てを書ききれなかったので3つの記事に分けました。
本記事は、完成形とコードの全容になります。

実装手順についての記事は下記になります。
【Swift】FirebaseUIを使ったTwitterログイン機能の実装方法②
【Swift】FirebaseUIを使ったTwitterログイン機能の実装方法③

環境
・Swift version 5.3
・XCode version 12.3
・CocoaPods version 1.10.1

前提として

CocoaPodsをインストールしていること
Twitter APIに登録していること
Firebase consoleに登録していること

完成形

ezgif.com-gif-maker (2).gif

ログイン後Firebase Authentication

ユーザが追加されているのがわかります。
スクリーンショット 2021-01-13 18.48.11.png

コード

AppDelegate.swift
import UIKit
import Firebase

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }

}
ViewController.swift
import UIKit
import Firebase
import FirebaseUI

class ViewController: UIViewController, FUIAuthDelegate {

    let authUI = FUIAuth.defaultAuthUI()
    let providers: [FUIAuthProvider] = [
        FUIOAuth.twitterAuthProvider()
    ]

    override func viewDidLoad() {
        super.viewDidLoad()

        authUI!.delegate = self
        authUI!.providers = providers

        checkLoggedIn()
    }

    // ログイン(ログイン失敗)後に呼ばれるメソッド
    func authUI(_ authUI: FUIAuth, didSignInWith user: User?, error: Error?) {
        // handle user and error as necessary
    }

    func checkLoggedIn() {

        Auth.auth().addStateDidChangeListener{auth, user in
            if user != nil{
                print("success")
            } else {
                print("fail")
                self.login()
            }
        }
    }

    func login() {
        let authViewController = authUI!.authViewController()
        self.present(authViewController, animated: true, completion: nil)
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[iOS][Objective-C] Objective-Cアプリ からWidgetを更新する方法

ラッパー(swiftファイル)を用意する

WidgetKitHelper.swift

import WidgetKit

    @available(iOS 14.0, *)
    @objcMembers final class WidgetKitHelper: NSObject {

          class func reloadAllWidgets(){

            #if arch(arm64) || arch(i386) || arch(x86_64)
            WidgetCenter.shared.reloadAllTimelines()
            #endif

          }
    }

swiftコードをインポート

#import "プロダクトネーム-Swift.h"
プロダクトネームとは
  1. Projectナビゲーター (Xcodeの左側)のTargetsセクションからをアプリを選択
  2. Build Settingsタブをクリック
  3. "Product Name"で検索

これで使用できます

    if (@available(iOS 14.0, *)) {
        [WidgetKitHelper reloadAllWidgets];
    }

バックグラウンド時に更新させる場合

- (void)applicationDidEnterBackground:(UIApplication *)application {
    if (@available(iOS 14.0, *)) {
        [WidgetKitHelper reloadAllWidgets];
    }
}

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RxSwiftのメソッドチェーン

はじめに

初めまして!
タップルでRxSwift武者修行中のせーたろです。

RxSwiftを書き始めてから知ったメソッドチェーンの備忘録兼メモです。

メソッドチェーンとは

メソッドを組み合わせた書き方をすることによって、関数型プログラミングの副作用を避ける方法を取り入れたプログラミングをし、より読みやすく宣言的なコードを書いています。
宣言的なコーディングを実現するため、メソッドチェ-ンによる処理の記述が基本であり重要です。

map と subscribe による例

// 入力されたInt型の値を2倍する
_ = Observable.just(10) 
.map { $0 * 2 } 
.subscribe(onNext: { print($0) // => 20 
})

型が同じ限り一生.mapとかの処理をつなげられるけど、
この場合.subscribeしたら型が変わるのでdisposeBagして終了

(多分このつなげて書くやつをつよつよの人は"比較的宣言的な書き方"と言ってるっぽいです)

そして、mapのクロージャの戻り値を Int → Stringにすると
購読できるイベントもInt → Stringになります。
map に使われているクロージャの戻り値によって購読できる型が変わるということです

RxSwiftのオペレータはジェネリクスを使ったインタフェースを定義することで、メソッドチェ-ンを実現しています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む