20210315のSwiftに関する記事は12件です。

Xcode シュミレーター @が打てない時の対処法

Xcodeのシュミレーターで「@」が打てない!!!

iOSのシュミレーターでキーボードから記号を入力すると、不思議なことに@[になったり、なんだか色々とおかしくなってた。。。

別に/とか:みたいな記号はユーザー入力で使われることは滅多に無いのでいいんですが、、、

@はログイン周りの処理で使うので、@が打てないのは困ります!!

かといって、シュミレーター内のキーボードを毎回使うのも面倒やし:confused:

解決法

スクリーンショット 2021-03-15 22.41.41.jpg

|/O>Keyboard>Connect Hardware Keyboardのチェックを外す→もう一度チェックをつける

よくわかりませんが、これだけで正常になりました。。。

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

[Swift]画面遷移をコードで記述する

はじめに

複雑な画面遷移や複数の起動経路を持つようなアプリの画面遷移に、Storyboardを使用して実装するとSegueが入り乱れ大変なことになるようです。

学習の記録も兼ねて、単純な画面遷移を実装しました。

目的

可読性が良い&改修のしやすいコードにすること

前提

  1. 画面の装飾や遷移のためのボタンなどはStoryboardで設置している
    ※実際は全てをStoryboardに任せる訳にはいかないが、今回はサンプルのコードを簡潔にするためこのような手法を取りました。
  2. FirstView -> SecondView -> ThirdView と単純な画面遷移のみ
  3. それぞれの画面につき、ViewControllerとStoryboardを一つずつ使用
  4. Info.plistのMain storyboard file base nameは削除する
  5. SceneDelegateは削除し使用しない
    ※SceneDelegateはiOS13から追加された機能となり、iOS12以前にも対応可能にするためには予め削除しておく必要がある。
    本記事ではSceneDelegateは使用せず、AppDelegateに起動コードを記述している。

4,5についての解説は本記事では省略しますが、以下の記事が分かりやすく参考になると思いますのでリンクさせて頂きました。いつもありがとうございます。

ファイル構成&プレビュー

ファイル構成 プレビュー

ソースコード

①AppDelegate

AppDelegate.swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

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

        let window = UIWindow(frame: UIScreen.main.bounds) // ウィンドウをインスタンス化する
        self.window = window 
        Router.showRoot(window: window) // 初期Viewの取得はRouterクラスで行う

        return true
    }
}

ViewControllerやNavigationControllerを取得するといった処理を、showRootというメソッドとしてRouterクラスに任せています。
UIWindowのみこちらでインスタンス化し、メソッドに引数として渡します。

②FirstViewController(最初のView)

FirstViewController.swift
import UIKit

class FirstViewController: UIViewController {
    // ボタンを押した時の処理
    @IBAction func tapGoSecond(_ sender: UIButton) {
        Router.showSecond(fromVC: self)
    }
}

遷移先のViewControllerを取得する処理をRouterクラスに任せています。
self.ViewControllerをメソッドの引数として渡します。

③SecondViewContrller(2つ目のView)

SecondViewController.swift
import UIKit

class SecondViewController: UIViewController {
    // ボタンを押した時の処理
    @IBAction func tapGoThird(_ sender: UIButton) {
        Router.showThird(fromVC: self)
    }   
}

同じく、遷移先のViewControllerを取得する処理をRouterクラスに任せています。
self.ViewControllerをメソッドの引数として渡します。

④Router

前出の3つのクラスから画面遷移のメソッドをそれぞれ受け取っており、それらの処理を書いています。

Router.swift
import UIKit

final class Router {

    // アプリ起動時にrootViewを取得する処理
    static func showRoot(window: UIWindow?) {
        let firstStoryboard = UIStoryboard(name: "First", bundle: nil)
        let firstVC = firstStoryboard.instantiateInitialViewController() as! FirstViewController
        let nav = UINavigationController(rootViewController: firstVC) // ナビゲーションコントローラーを定義。引数で最下層となるViewを指定
        window?.rootViewController = nav
        window?.makeKeyAndVisible()
    }

    // 2つ目のViewへ画面遷移する処理
    static func showSecond(fromVC: UIViewController) {
        let secondStoryboard = UIStoryboard(name: "Second", bundle: nil)
        let secondVC = secondStoryboard.instantiateInitialViewController() as! SecondViewController
        show(fromVC: fromVC, nextVC: secondVC)
    }

    // 3つ目のViewへ画面遷移する処理
    static func showThird(fromVC: UIViewController) {
        let thirdStoryboard = UIStoryboard(name: "Third", bundle: nil)
        let thirdVC = thirdStoryboard.instantiateInitialViewController() as! ThirdViewController
        show(fromVC: fromVC, nextVC: thirdVC)
    }

    // 実際に画面を遷移させる処理
    private static func show(fromVC: UIViewController, nextVC: UIViewController) {
        if let nav = fromVC.navigationController {
            nav.pushViewController(nextVC, animated: true)
        } else {
            fromVC.present(nextVC, animated: true, completion: nil)
        }
    }  
}

instantiateInitialViewControllerとは

instantiateInitialViewControllerはStoryboardクラスのメソッドで、「is initial view controller」が設定されているViewControllerを取得できる
※引数にstoryboardIDを直接指定して取得することも可能

showについて

showメソッドはNavigationControllerの有無をアンラップによって判別し、結果によって画面の表示方法を変えているもの

makeKeyAndVisibleとは

UIWindowクラスのインスタンスメソッド。
AppleDeveloperを見ると、

Shows the window and makes it the key window.
ウィンドウを表示し、それをキーウィンドウにします

とあります。

~以下は自分の認識なので間違っているかもしれません~
このメソッドを実行することによってキーウィンドウの指定と表示を行う。つまり、ウィンドウの直上に設置するrootViewを決めているということ。

今回のサンプルでいうと、

window?.rootViewController = UINavigationController(rootViewController: firstVC)
// windowのrootViewControllerプロパティにはfirstVCが代入されている
window?.makeKeyAndVisible()
// 現在のwindowの状態をキーウィンドウとして表示する

ということになると解釈しています。

後語り

以上がコードで書く画面遷移のやり方となります。

今回はただ画面を進めるだけのシンプルな画面遷移でしたが、複雑な画面遷移を必要とするアプリケーションの場合、このように切り離すことで、可読性が良くなり改修もしやすくなると思います。

また、UIWindowの扱いであったりrootViewControllerの差し替えなどについては勉強不足で理解しきれていませんので、今後の課題としていきます。

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

[Swift] 画面遷移をコードで記述する

はじめに

複雑な画面遷移や複数の起動経路を持つようなアプリの画面遷移に、Storyboardを使用して実装するとSegueが入り乱れ大変なことになるようです。

学習の記録も兼ねて、単純な画面遷移を実装しました。

目的

可読性が良い&改修のしやすいコードにすること

前提

  1. 画面の装飾や遷移のためのボタンなどはStoryboardで設置している
    ※実際は全てをStoryboardに任せる訳にはいかないが、今回はサンプルのコードを簡潔にするためこのような手法を取りました。
  2. FirstView -> SecondView -> ThirdView と単純な画面遷移のみ
  3. それぞれの画面につき、ViewControllerとStoryboardを一つずつ使用
  4. Info.plistのMain storyboard file base nameは削除する
  5. SceneDelegateは削除し使用しない
    ※SceneDelegateはiOS13から追加された機能となり、iOS12以前にも対応可能にするためには予め削除しておく必要がある。
    本記事ではSceneDelegateは使用せず、AppDelegateに起動コードを記述している。

4,5についての解説は本記事では省略しますが、以下の記事が分かりやすく参考になると思いますのでリンクさせて頂きました。いつもありがとうございます。

ファイル構成&プレビュー

ファイル構成 プレビュー

ソースコード

①AppDelegate

AppDelegate.swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

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

        let window = UIWindow(frame: UIScreen.main.bounds) // ウィンドウをインスタンス化する
        self.window = window 
        Router.showRoot(window: window) // 初期Viewの取得はRouterクラスで行う

        return true
    }
}

ViewControllerやNavigationControllerを取得するといった処理を、showRootというメソッドとしてRouterクラスに任せています。
UIWindowのみこちらでインスタンス化し、メソッドに引数として渡します。

②FirstViewController(最初のView)

FirstViewController.swift
import UIKit

class FirstViewController: UIViewController {
    // ボタンを押した時の処理
    @IBAction func tapGoSecond(_ sender: UIButton) {
        Router.showSecond(fromVC: self)
    }
}

遷移先のViewControllerを取得する処理をRouterクラスに任せています。
self.ViewControllerをメソッドの引数として渡します。

③SecondViewContrller(2つ目のView)

SecondViewController.swift
import UIKit

class SecondViewController: UIViewController {
    // ボタンを押した時の処理
    @IBAction func tapGoThird(_ sender: UIButton) {
        Router.showThird(fromVC: self)
    }   
}

同じく、遷移先のViewControllerを取得する処理をRouterクラスに任せています。
self.ViewControllerをメソッドの引数として渡します。

④Router

前出の3つのクラスから画面遷移のメソッドをそれぞれ受け取っており、それらの処理を書いています。

Router.swift
import UIKit

final class Router {

    // アプリ起動時にrootViewを取得する処理
    static func showRoot(window: UIWindow?) {
        let firstStoryboard = UIStoryboard(name: "First", bundle: nil)
        let firstVC = firstStoryboard.instantiateInitialViewController() as! FirstViewController
        let nav = UINavigationController(rootViewController: firstVC) // ナビゲーションコントローラーを定義。引数で最下層となるViewを指定
        window?.rootViewController = nav
        window?.makeKeyAndVisible()
    }

    // 2つ目のViewへ画面遷移する処理
    static func showSecond(fromVC: UIViewController) {
        let secondStoryboard = UIStoryboard(name: "Second", bundle: nil)
        let secondVC = secondStoryboard.instantiateInitialViewController() as! SecondViewController
        show(fromVC: fromVC, nextVC: secondVC)
    }

    // 3つ目のViewへ画面遷移する処理
    static func showThird(fromVC: UIViewController) {
        let thirdStoryboard = UIStoryboard(name: "Third", bundle: nil)
        let thirdVC = thirdStoryboard.instantiateInitialViewController() as! ThirdViewController
        show(fromVC: fromVC, nextVC: thirdVC)
    }

    // 実際に画面を遷移させる処理
    private static func show(fromVC: UIViewController, nextVC: UIViewController) {
        if let nav = fromVC.navigationController {
            nav.pushViewController(nextVC, animated: true)
        } else {
            fromVC.present(nextVC, animated: true, completion: nil)
        }
    }  
}

instantiateInitialViewControllerとは

instantiateInitialViewControllerはStoryboardクラスのメソッドで、「is initial view controller」が設定されているViewControllerを取得できる
※引数にstoryboardIDを直接指定して取得することも可能

showについて

showメソッドはNavigationControllerの有無をアンラップによって判別し、結果によって画面の表示方法を変えているもの

makeKeyAndVisibleとは

UIWindowクラスのインスタンスメソッド。
AppleDeveloperを見ると、

Shows the window and makes it the key window.
ウィンドウを表示し、それをキーウィンドウにします

とあります。

~以下は自分の認識なので間違っているかもしれません~
このメソッドを実行することによってキーウィンドウの指定と表示を行う。つまり、ウィンドウの直上に設置するrootViewを決めているということ。

今回のサンプルでいうと、

window?.rootViewController = UINavigationController(rootViewController: firstVC)
// windowのrootViewControllerプロパティにはfirstVCが代入されている
window?.makeKeyAndVisible()
// 現在のwindowの状態をキーウィンドウとして表示する

ということになると解釈しています。

後語り

以上がコードで書く画面遷移のやり方となります。

今回はただ画面を進めるだけのシンプルな画面遷移でしたが、複雑な画面遷移を必要とするアプリケーションの場合、このように切り離すことで、可読性が良くなり改修もしやすくなると思います。

また、UIWindowの扱いであったりrootViewControllerの差し替えなどについては勉強不足で理解しきれていませんので、今後の課題としていきます。

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

オリジナルアプリ作成中に理解できていなかった基礎解説

オリジナルアプリ作成中にうまく実装ができず、詰まってしまった箇所の深掘りをアウトプットします!
もし誤った情報や、もっと効率の良い書き方などがあった場合指摘してくださると助かります!

完成形

※現段階ではオリジナルアプリ自体は完成していません
完成形

目次

実装できなかった箇所

今回実装しようとした内容は、曜日表記の日本語化です
自分の作りたいオリジナルアプリのコンセプトが『高齢者の方でも使いやすいアプリ』なので、横文字や英語はなるべく使わないようにしたいため、日本語に変更します。

英語表記のカレンダー

英語表記

日本語化できなかった記載方法

ViewController.swift
    override func viewWillAppear() {
        super.viewWillAppear()
            // calendarの曜日部分を日本語表記に変更
            calendar.calendarWeekdayView.weekdayLabels[0].text = "日"
            calendar.calendarWeekdayView.weekdayLabels[1].text = "月"
            calendar.calendarWeekdayView.weekdayLabels[2].text = "火"
            calendar.calendarWeekdayView.weekdayLabels[3].text = "水"
            calendar.calendarWeekdayView.weekdayLabels[4].text = "木"
            calendar.calendarWeekdayView.weekdayLabels[5].text = "金"
            calendar.calendarWeekdayView.weekdayLabels[6].text = "土"
    }

参考記事などを見ながら進めていましたが日本語に変化しませんでした?

overrideの詳細

なぜ実装できないのかエラー文も出ていないので、上記で記載されているoverrideについて詳しく深掘りしてみました

overrideとは、端的の言うと親のメソッドを上書きして使いたい時に使います。
今回の実装内容としては親(デフォルトのカレンダー)の曜日を(日本語表記)に上書きしたいため使い方としては間違っていないはず!

あと残された可能性としてはviewWillAppearの部分か、そもそも日本語に表示するための記載が間違っている
次はviewWillAppearの部分を詳しく深掘りします

UIViewControllerのライフサイクル

viewWillAppearについて調べた結果
結論から言うと、この記載が原因で日本語表記にできていませんでした。
viewWillAppear以外にviewDidLoadviewWillDisappearなどがあります
それぞれ初期表示、画面に表示される直前や直後、画面から非表示になる直後や直前など意味が異なってきます。
今回実装したい内容は初期表示時に変わってもらいたいのでviewDidLoadを使用します

修正後

ViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
            // calendarの曜日部分を日本語表記に変更
            calendar.calendarWeekdayView.weekdayLabels[0].text = "日"
            calendar.calendarWeekdayView.weekdayLabels[1].text = "月"
            calendar.calendarWeekdayView.weekdayLabels[2].text = "火"
            calendar.calendarWeekdayView.weekdayLabels[3].text = "水"
            calendar.calendarWeekdayView.weekdayLabels[4].text = "木"
            calendar.calendarWeekdayView.weekdayLabels[5].text = "金"
            calendar.calendarWeekdayView.weekdayLabels[6].text = "土"
    }

修正後の表示

完成形

無事曜日の表記を日本語化することに成功しました!

まとめ

今回『問題解決のプロセス』と『基礎知識の重要さ』を実感しました。
基礎が理解できていなかったためどこが間違っているのかすらわかりませんでした、こういった場面は今後もありそうですが今回のようにわからない場所をがむしゃらに調べることの重要性も改めて理解できました!
それらの知識をQiitaでしっかりアウトプットしていきます

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

オリジナル作成中に理解できていなかった基礎解説

オリジナルアプリ作成中にうまく実装ができず、詰まってしまった箇所の深掘りをアウトプットします!
もし内容誤った情報や、もっと効率の良い書き方などがあった場合指摘してくださると助かります!

完成形

※現段階ではオリジナルアプリ自体は完成していません
完成形

目次

実装できなかった箇所

今回実装しようとした内容は、曜日表記の日本語化です
自分の作りたいオリジナルアプリのコンセプトが『高齢者の方でも使いやすいアプリ』なので、横文字や英語はなるべく使わないようにしたいため、日本語に変更します。

英語表記のカレンダー

英語表記

日本語化できなかった記載方法

ViewController.swift
    override func viewWillAppear() {
        super.viewWillAppear()
            // calendarの曜日部分を日本語表記に変更
            calendar.calendarWeekdayView.weekdayLabels[0].text = "日"
            calendar.calendarWeekdayView.weekdayLabels[1].text = "月"
            calendar.calendarWeekdayView.weekdayLabels[2].text = "火"
            calendar.calendarWeekdayView.weekdayLabels[3].text = "水"
            calendar.calendarWeekdayView.weekdayLabels[4].text = "木"
            calendar.calendarWeekdayView.weekdayLabels[5].text = "金"
            calendar.calendarWeekdayView.weekdayLabels[6].text = "土"
    }

参考記事などを見ながら進めていましたが日本語に変化しませんでした?

overrideの詳細

なぜ実装できないのかエラー文も出ていないので、上記で記載されているoverrideについて詳しく深掘りしてみました

overrideとは、端的の言うと親のメソッドを上書きして使いたい時に使います。
今回の実装内容としては親(デフォルトのカレンダー)の曜日を(日本語表記)に上書きしたいため使い方としては間違っていないはず!

あと残された可能性としてはviewWillAppearの部分か、そもそも日本語に表示するための記載が間違っている
次はviewWillAppearの部分を詳しく深掘りします

UIViewControllerのライフサイクル

viewWillAppearについて調べた結果
結論から言うと、この記載が原因で日本語表記にできていませんでした。
viewWillAppear以外にviewDidLoadviewWillDisappearなどがあります
それぞれ初期表示、画面に表示される直前や直後、画面から非表示になる直後や直前など意味が異なってきます。
今回実装したい内容は初期表示時に変わってもらいたいのでviewDidLoadを使用します

修正後

ViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
            // calendarの曜日部分を日本語表記に変更
            calendar.calendarWeekdayView.weekdayLabels[0].text = "日"
            calendar.calendarWeekdayView.weekdayLabels[1].text = "月"
            calendar.calendarWeekdayView.weekdayLabels[2].text = "火"
            calendar.calendarWeekdayView.weekdayLabels[3].text = "水"
            calendar.calendarWeekdayView.weekdayLabels[4].text = "木"
            calendar.calendarWeekdayView.weekdayLabels[5].text = "金"
            calendar.calendarWeekdayView.weekdayLabels[6].text = "土"
    }

修正後の表示

完成形

無事曜日の表記を日本語化することに成功しました!

まとめ

今回『問題解決のプロセス』と『基礎知識の重要さ』を実感しました。
基礎が理解できていなかったためどこが間違っているのかすらわかりませんでした、こういった場面は今後もありそうですが今回のようにわからない場所をがむしゃらに調べることの重要性も改めて理解できました!
それらの知識をQiitaでしっかりアウトプットしていきます

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

[Swift] Firebase-Authentication(新規登録)を使ってみた

概要

Firebaseを使ってみたい!ということで、
サンプルアプリを通して学習していきます。

第一回目は、認証機能を用意してくれているAuthenticationの新規ユーザー登録です。
今回はメールアドレスでの登録を使いました。

※注意
各UIView(部品)はコードで実装しております。
Storyboardを使用しているからは注意してください。

完成品

サクッとコードがみたい場合はこちらです。
https://github.com/ksy781/FirebaseAuthentication/blob/main/FirebaseAuthentication/ViewController.swift

環境

ツール バージョン
Xcode 12.4
Swift 5.3.2
Cocoapods 1.10.1
FirebaseAuth 7.7.0

事前準備(設定)

  • CocoapodsでFirebaseAuthをインストールしておきます。
  • Firebase側でアプリ登録をしておきます。
  • Firebase側のメール認証を有効化します。 スクリーンショット 2021-03-15 16.09.12.png

実践

  • Firebaseのインポート設定
    • AppDelegateファイルへFirebaseをインポートします。
    • FirebaseApp.configure()を記載します。
       ⇨ これでアプリ内でFirebaseが用意してくれている設定を利用することができます。
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
    }
  • 登録機能の実装
    • ボタンを押下したらFirebase側へ入力内応を登録(通信)してくれます。
    • createUserはFirebase側で用意したメソッドで、その中に入力値とエラーハンドリングを記載します。
ViewController.swift
// MARK: - Actions
@objc func didTapLoginButton() {
    guard let email = emailTextField.text else { return }
    guard let password = passwordTextField.text else { return }

    Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
        if let error = error {
            self.alert(settitle: "エラー", setmessage: "新規作成に失敗しました!")
            return
        }

        guard let uid = authResult?.user.uid else { return }
        self.alert(settitle: "成功", setmessage: "新規作成しました!")
    }
}

無事、登録できました!
スクリーンショット 2021-03-15 19.22.48.png

ここからどんどんFirebase使ってみたいと思います!

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

【Swift】ライブラリ Instantiate を使用した際のエラー "Fatal error: Unexpectedly found nil while unwrapping an Optional value"

エラー

Storyboard+UIViewController.swift
    public extension StoryboardInstantiatable where Self: UIViewController {
        init(with dependency:Dependency) {
            let storyboard = (Self.self as StoryboardType.Type).storyboard
            switch Self.instantiateSource {
            case .initial:

                // ここで落ちた
                self = storyboard.instantiateInitialViewController() as! Self
            case .identifier(let identifier):

                self = storyboard.instantiateViewController(withIdentifier: identifier) as! Self
            }
            if self is ViewLoadBeforeInject {
                _ = self.view
            }
            self.inject(dependency)
        }
    }

解決策

Controllerの Is Initial View Controller にチェックをする。

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

Firebaseを使用してiOSアプリにプッシュ通知機能を実装する

はじめに

FirebaseのCloud Messagingを使用してアプリにプッシュ通知を実装します。

前提条件

Apple Developer Programの登録と、Firebaseを導入していること前提で書いていきます。

プッシュ通知の仕組み

iOSの場合、Appleが提供しているプッシュ通知サービスAPNs(Apple Push Notification Service)を介して
プッシュ通知を配信しています。

push_Notification.png
出典:【Swift】iOSアプリにプッシュ通知を実装したサンプルアプリを作ってみた

このサービスのおかげでCloudMessagingからプッシュ通知が送れるという訳です。

実装する前に

まずは、CloudMessagingを使用するために必要なライブラリをインストールしましょう。

因みに自分はSPMでインストールしました。
Swift Package Manager (SwiftPM) を使ってみよう ~導入編~

実装

・Capabilityを設定する

まずはプッシュ通知に必要なCapabilityを設定しましょう。

1.TARGETS > Signing & Capabilities > + Capability をクリックする
2.Background ModesとPush Notificationsを追加する
3.Background Modes内のRemote notifiationsにチェックする

以上の流れを終えると、プロジェクト内にプロジェクト名.entitlementsファイルが追加されます。
スクリーンショット 2021-03-15 14.57.17.png

このファイルは、プッシュ通知の登録時に開発環境と本番環境のどちらのAPNsを使用するかを自動的に指定してくれます。
APS Environment Entitlement

・APNs認証キーを発行する

APNsを介してCloud Messagingに接続するにはAPNs認証キーを発行して
Firebaseにアップロードしなくてはいけません。

1.Apple Developer Account > Certificates, Identifiers & Profiles > Keys > Keys+をクリックする
2.ページ内でKey Nameを入力 > Apple Push Notifications service (APNs)をチェック > continueをクリックする
3.APNs認証キーが発行されたらダウンロードする

これでFirebaseにアップロードするAPNs認証キーが取得できました。

・Firebaseプロジェクト内でAPNs認証キーをアップロードする

それでは、APNs認証キーをFirebaseにアップロードしましょう。

1.「プロジェクトの概要」の左にある歯車マークから「プロジェクトを設定」をクリックする
2.ページ上部にあるCloud Messaging > iOSアプリの構成 > APNs認証キーからアップロードする
3.APNs認証キーをアップロードする際に必要なキーIDとチームIDを入力してアップロードを完了させる

キーIDは、Apple Developer AccountのKeys > 自分のAPNs認証キー > Key IDから確認できます。

チームIDは、Apple Developer AccountのIdentifiers > 自分のプロジェクト > App ID Prefixから確認できます。

・実装コードを書く

必要最低限のコードのみを書きますのでご了承下さい。

import UIKit
import Firebase

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Coloud Messagingのデリゲート
        Messaging.messaging().delegate = self

        // 通知関連のアクションを処理
        UNUserNotificationCenter.current().delegate = self

        // 通知の許可をユーザーにリクエストする
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
            if let error = error {
                print(error.localizedDescription)
                return
            }
            if granted {
                // aregisterForRemoteNotificationsは必ずメインスレッドで実行する
                DispatchQueue.main.async {
                    // Appleプッシュ通知サービスを介してリモート通知を受信するための登録を行う
                    application.registerForRemoteNotifications()
                }
            }
        }
        return true
    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {
    // アプリがフォアグラウンドで通知を受け取ったときに呼ばれる
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

            let userInfo = notification.request.content.userInfo

            print("========== Print full message =========")
            print(userInfo)
            print("===============")
            //表示方法を決める
            completionHandler([.banner, .sound, .badge])
        }
}
extension AppDelegate: MessagingDelegate {
    // FCMトークンが利用可能になったり、更新されたりすると呼ばれる
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("===============")
        print("Firebase registration token: \(String(describing: fcmToken))")
        print("===============")
    }
}

因みにiOS10以降なら上記のコードで大丈夫ですが、iOS10未満だと実装コードが変わってきます
iOS で Firebase Cloud Messaging クライアント アプリを設定する | Firebase

・プッシュ通知を送る

Firebaseプロジェクト内のCloud Messagingからプッシュ通知を送りましょう。

テスト送信をしたい場合は、テスト メッセージを送信から送ることができます。
スクリーンショット 2021-03-15 15.58.06.png

テスト メッセージを送信をクリックし、FCM登録トークンを追加を入力すると
テスト送信を端末に送ることが出来ます。
スクリーンショット 2021-03-15 16.01.38.png

因みにFCM登録トークンは先ほど記述したデリゲートメソッドから吐き出されます↓

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("===============")
        print("Firebase registration token: \(String(describing: fcmToken))")
        print("===============")
    }

以下のようなプッシュ通知が端末に送られてきたら成功です。
IMG_6625.jpg

おわりに

画像や動画もプッシュ通知と一緒に送ることができますが、調べてみると難しそうでした。

もし、実装できたらQiitaにまとめようと思います。

参考

Firebase Cloud Messagingを使ってアプリに通知機能を実装する
Push Notifications with Firebase iOS Swift 5 & Xcode 11.5 | Youtube

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

Firebaseを使用してiOSアプリにプッシュ通知を実装する

はじめに

FirebaseのCloud Messagingを使用してアプリにプッシュ通知を実装します。

前提条件

Apple Developer Programの登録と、Firebaseを導入していること前提で書いていきます。

プッシュ通知の仕組み

iOSの場合、Appleが提供しているプッシュ通知サービスAPNs(Apple Push Notification Service)を介して
プッシュ通知を配信しています。

push_Notification.png
出典:【Swift】iOSアプリにプッシュ通知を実装したサンプルアプリを作ってみた

このサービスのおかげでCloud Messagingからプッシュ通知が送れるという訳です。

実装する前に

まずは、Cloud Messagingを使用するために必要なライブラリをインストールしましょう。

因みに自分はSPMでインストールしました。
Swift Package Manager (SwiftPM) を使ってみよう ~導入編~

実装

・Capabilityを設定する

まずはプッシュ通知に必要なCapabilityを設定しましょう。

1.TARGETS > Signing & Capabilities > + Capability をクリックする
2.Background ModesとPush Notificationsを追加する
3.Background Modes内のRemote notifiationsにチェックする

以上の流れを終えると、プロジェクト内にプロジェクト名.entitlementsファイルが追加されます。
スクリーンショット 2021-03-15 14.57.17.png

このファイルは、プッシュ通知の登録時に開発環境と本番環境のどちらのAPNsを使用するかを自動的に指定します。
APS Environment Entitlement

・APNs認証キーを発行する

APNsを介してCloud Messagingに接続するにはAPNs認証キーを発行して
Firebaseにアップロードしなくてはいけません。

1.Apple Developer Account > Certificates, Identifiers & Profiles > Keys > Keys+をクリックする
2.ページ内でKey Nameを入力 > Apple Push Notifications service (APNs)をチェック > continueをクリックする
3.APNs認証キーが発行されたらダウンロードする

これでFirebaseにアップロードするAPNs認証キーが取得できました。

・Firebaseプロジェクト内でAPNs認証キーをアップロードする

それでは、APNs認証キーをFirebaseにアップロードしましょう。

1.「プロジェクトの概要」の左にある歯車マークから「プロジェクトを設定」をクリックする
2.ページ上部にあるCloud Messaging > iOSアプリの構成 > APNs認証キーからアップロードする
3.APNs認証キーをアップロードする際に必要なキーIDとチームIDを入力してアップロードを完了させる

キーIDは、Apple Developer AccountのKeys > 自分のAPNs認証キー > Key IDから確認できます。

チームIDは、Apple Developer AccountのIdentifiers > 自分のプロジェクト > App ID Prefixから確認できます。

・実装コードを書く

必要最低限のコードのみを書きますのでご了承下さい。

import UIKit
import Firebase

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Coloud Messagingのデリゲート
        Messaging.messaging().delegate = self

        // 通知関連のアクションを処理
        UNUserNotificationCenter.current().delegate = self

        // 通知の許可をユーザーにリクエストする
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
            if let error = error {
                print(error.localizedDescription)
                return
            }
            if granted {
                // aregisterForRemoteNotificationsは必ずメインスレッドで実行する
                DispatchQueue.main.async {
                    // Appleプッシュ通知サービスを介してリモート通知を受信するための登録を行う
                    application.registerForRemoteNotifications()
                }
            }
        }
        return true
    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {
    // アプリがフォアグラウンドで通知を受け取ったときに呼ばれる
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
            let userInfo = notification.request.content.userInfo
            print("========== Print full message =========")
            print(userInfo)
            print("===============")

            // プッシュ通知の表示方法を決める
            completionHandler([.banner, .sound, .badge])
        }
}
extension AppDelegate: MessagingDelegate {
    // FCMトークンが利用可能になったり、更新されたりすると呼ばれる
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("===============")
        print("Firebase registration token: \(String(describing: fcmToken))")
        print("===============")
    }
}

因みにiOS10以降なら上記のコードでOKですが、iOS10未満だと実装コードが変わってきます
iOS で Firebase Cloud Messaging クライアント アプリを設定する | Firebase

・プッシュ通知を送る

Firebaseプロジェクト内のCloud Messagingからプッシュ通知を送りましょう。

テスト送信をしたい場合は、テスト メッセージを送信から送ることができます。

Firebaseのプロジェクト上でプッシュ通知を送ると開発・本番用関係なく送信されますので
開発用ではこちらでプッシュ通知を送りましょう。

スクリーンショット 2021-03-15 15.58.06.png

テスト メッセージを送信をクリックし、FCM登録トークンを追加を入力すると
テスト送信を端末に送ることが出来ます。
スクリーンショット 2021-03-15 16.01.38.png

FCM登録トークンは先ほど記述したデリゲートメソッドから吐き出されます。

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("===============")
        print("Firebase registration token: \(String(describing: fcmToken))")
        print("===============")
    }

以下のようなプッシュ通知が端末に送られてきたら成功です。
IMG_6625.jpg

おわりに

画像や動画もプッシュ通知と一緒に送ることができますが、調べてみると難しそうでした。

もし、実装できたらQiitaにまとめようと思います。

参考

Firebase Cloud Messagingを使ってアプリに通知機能を実装する
Push Notifications with Firebase iOS Swift 5 & Xcode 11.5 | Youtube

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

Mapture愛用者が「Fuwari」に機能追加して公開しました ?

普段、スクリーンショット拡張アプリの「Mapture」を愛用していた自分が、今回Swiftの勉強を兼ねて、オープンソースとして公開されている「Fuwari」に機能追加をして公開しました。
開発の経緯や今回追加した機能、初めてSwiftを書いた感想などを書いていきたいと思います。

開発経緯

コードを書いている上で、ドキュメントや参考ページを見ながら作業をすることが多々あると思いますが、そんな時自分は「Mapture」というソフトを使っていました。
機能としては、画面の好きな範囲を選択してスクショを撮影し、その画像を画面上に保持しておくことができます。

image.png
チートシートを見ながらターミナルを叩く様子(Mapture配布サイトより引用)

このMaptureには「Gyazoに送る」という項目があって、元は撮影したスクショをGyazoに転送して共有できたのですが、ここ数年は使えなくなっていました。
2014年を最後に長らく更新されておらず、おそらくAPIが使えなくなったのでしょう。

もう少し頻繁にメンテナンスされている代替アプリはないかと探していたときに見つけたのが、「Fuwari」でした。
2018年に公開されており、Qiitaで開発記事が上がっているほか、いろんなサイト様で紹介されているイケイケっぷり。

モダンなアイコンが素敵で、早速乗り換えを検討したのですが……

  • ワークスペース間で画像を共有できない(ワークスペース切り替えてもついてきてくれない)
  • 透明度を変更できない
  • クラッシュするバグがある
  • メモリ使用率が雪だるま式に増えていく

と、所々不具合や、機能的な物足りなさ(Maptureに慣れていた所為)を感じてしまいました。

更新も途絶えてしまっているようなので、「せっかくMITで公開してくれているんだし、自分で直して公開しよう!」と思い立ったのが、今回の経緯です。

公開したアプリ

Githubリポジトリはこちらです。
元のリポジトリをforkして、再配布形式で公開させていただいています。

デモ動画はこちら↓
image.png

追加した機能

今回追加した機能や、バグフィックスの一覧です。

追加機能

  • ➕右クリックメニューからGyazoに送信できる機能を追加しました
  • ➕画像の拡大縮小をマウスドラッグで変更可能にしました
  • ➕マウスウィールでキャプチャの透明度を変更できるようにしました
  • ➕OS標準のダークテーマに対応しました
  • ➕設定画面からドラッグ移動時の透明度を指定できるようにしました

変更箇所

  • ✨Apple Siliconに対応したUniversal Binaryにしました
  • ✨キャプチャのデフォルトショートカットをCmd+Shift+mに変更しました
  • ✨キャプチャが全てのワークスペースで表示されるように変更しました

バグフィックス

  • ?キャプチャをESCでキャンセルするとアプリがクラッシュする問題を修正
  • ?メモリーリークが発生していた問題を修正

機能比較

下はOS標準のスクショ機能も含め、各アプリを比較した表です。

Fuwari(sskmy) Fuwari(origin) Mapture OS標準(Cmd+Shift+4)
画面上にキープ ✖️
ワークスペース間で共有 ✖️ -
透明度の変更 ✖️ -
共有リンクの生成(Gyazo) ✖️ ✖️ ▲(icloud)
ショートカットキーの設定 ✖️ ✖️
ゴミファイルが残らない ✖️ ✖️

はじめてのSwift

普段はTypescript中心にWebフロントやReactNativeばかり触っていて、Swiftをがっつり触ったのは初めてでした。
なので今回の機能追加は、とても学びになることが多かったです。

特に学びになった(足止め食らった)もの↓

  • clone直後、フレームワークが最新のCarthageでビルドできなかった(超初歩)
  • storyboardと@IBOutletする方法(超初歩)
  • NSImageをbase64に変換してmultipart/form-dataで送信する方法
  • Xcode projectで環境変数(.env)を使う最適解
  • メモリリークという概念に初めて触れた

ここら辺は時間がある時に別途記事にしたいですね。

Swiftという言語の書き方については、Typescriptに似たような雰囲気があって、比較的スムーズに書くことができました。
Xcodeの補完やFix機能が優秀というのもあるのかもしれません。

今後の開発

Maptureの代替をようやく見つけた(作った)ので、自分自身がヘビーユーザとなり今後もメンテナンスしていくつもりです。
Githubで公開してあるので、不具合や追加機能のご要望等あればお待ちしております!
コメント欄や、Twitter (@sskmy1024r) での感想も承ります。

なお、オリジナルの更新が途絶えてしまっているので今回このような形で公開しておりますが、開発が再開された場合、ソースコードの提供を含めてオリジナル版の発展に貢献する所存です。

最後に

今回の開発を得て、オープンソースプロジェクトの偉大さを改めて感じました。
触れたことのない言語で1からこのアプリを開発をすることは、今の自分には到底無理だと思いました。
素晴らしいアプリを開発していただき、かつオープンソースとして公開してくださっている@kentya6様、本当にありがとうございます?‍♂️

そして世の中のOSSを公開してくださっている皆さん、OSSを使って新しい価値を生み出している皆さん、OSSを使ってくれている皆さん、ありがとうございます!!!

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

[Mac]Touch Barをカスタマイズするアプリ'Pock'のプラグイン開発

はじめに

まずは僕が使っているMacBookProのTouch Barをご覧ください!
touchbar.png

左から、escキーストップウォッチDock音楽プレーヤ明るさ・音量設定となってます。良い評判はあまり聞こえてくることのないMacBook ProのTouch Barですが、こんな感じでカスタマイズして使用すると割と便利だったりします。

Pockとは

このようにTouch Barをカスタマイズするアプリの一つがPockというものです。他にもBetterTouchToolというものがありますがこちらは有料であるのに対し、Pockはオープンソースで開発されており無料で使用することができます。(BTTも便利なので利用していますが。。)
GitHubのリポジトリ

install方法

HomeBrewで簡単にインストールできます。

brew install pock

こちらの公式サイトからもインストールできます。
[2021.3.14]
開発者様のツイートより、現在公式サイト復旧中であるとのことですのでgithubよりダウンロードするのが良いかもしれません。


初めて起動した際、いくつかアクセシビリティやプライバシーの権限が求められますので各自判断して許可を与えてください。

Widget

Pockをインストールするとデフォルトで、DockNow PlayingESC keyStatusControl CenterWeatherの6つが使用できるようになります。(詳しい内容はこちらをご覧ください)
サードパーティ製のプラグインも開発できるようになってはいるようですが、現状公開されているものはほとんど見つけることが出来ませんでした。

機能

マウスでの操作

Pockの設定からEnable Mouse controlをオンにするとマウスでTouch Bar上のアイテムを操作できるようになります。Widget側が対応していないとクリックしても反応しないので注意が必要です。デフォルトでインストールされるwidgetの中にも対応していないものもありました。

通常のTouch Bar表示との切り替え

macOS標準やアプリ標準のTouch Bar表示へも簡単に切り替えることが出来ます。キーボードのcontrolを2回早押しすると切り替わります。

Pockプラグインの開発

Pockプラグイン開発には、PockKitというライブラリを使用することとなります。こちらにドキュメントが公開されるようですが、現状ではあまり詳細には記述されていないようです。そのため各自でライブラリのコードを読む必要がありますが、本記事で簡単に解説します。

1. プラグインテンプレートをダウンロードする。

こちらのページからダウンロードします。初めから自分で作成したい場合は、Xcodeのプロジェクト作成から、macOS->Bundleと進み、Bundle Extensionの欄をpockに変更して作成してください。
以下のようなファイルが確認できると思います。
スクリーンショット 2021-03-15 13.51.51.png

2. PockKitフレームワークのダウンロード

ダウンロードしたディレクトリ配下に移動しpod installコマンドでPockKitをダウンロードします。
今のところSwift Packageには対応していないようですが、ここにはSwift Packageから入れられると書いてあるので将来的には対応するのだろうと思われます。

3. リネーム

Xcodeプロジェクト自体の名前など各自好きな名前に変更してください。SampleWidgetクラスの名前を変更する場合、Info.plistPrincipal classの部分も変更する必要があります。

4. 表示したいviewの実装

表示したいviewを実装します。viewの実装に関しては通常のCocoaアプリの開発と変わりはないので割愛させていただきます。xibを使ったviewでも大丈夫です。(Bundleの指定には注意してください、自分も引っかかったのでw)

5. widgetクラスの実装

widgetクラスは、PKWidgetプロトコルに準拠している必要があります。

・ identifier

Touch Bar上のitemの識別子です。無難に逆ドメイン名を指定しておくと良いと思います。

・ customizationLabel

Pock上で使用されるwidgetのタイトルに当たる部分です。具体的にはTouch barカスタマイズ画面やWidget設定画面で表示されます。

・ view

表示したいviewのインスタンスを指定します。Touch Barの高さは30pointですので、作成するviewについてはこれより小さくある必要があります。

6. Build&Install

ビルドすると.pockという拡張子のファイルができるので、pockのInstall Widget...をクリックして表示された画面にドラッグ&ドロップしてインストールします。するとpockからリロードを求められるのでリロードを行うと完了です。カスタマイズ画面から作成したwidgetを追加できるようになっていると思います。
また、普通に.pockファイルをダブルクリックするだけでもインストールできるかと思います。

オプション

マウスでの操作

WidgetクラスをPKScreenEdgeMouseDelegateプロトコルに準拠させることでマウスでの操作に対応することが出来ます。
以下が実装が必要なメソッドとなっています。

/// マウスがTouch Bar上に侵入した時(Widgetのviewに侵入した時ではないので注意)
func screenEdgeController(_ controller: PKScreenEdgeController, mouseEnteredAtLocation location: NSPoint, in view: NSView)

/// マウスがTouch Bar上を移動した時
func screenEdgeController(_ controller: PKScreenEdgeController, mouseMovedAtLocation location: NSPoint, in view: NSView)

///マウスがTouch Bar上の任意の点をクリックした時
func screenEdgeController(_ controller: PKScreenEdgeController, mouseClickAtLocation location: NSPoint, in view: NSView)

//マウスがTouch Bar上から退避した時
func screenEdgeController(_ controller: PKScreenEdgeController, mouseExitedAtLocation location: NSPoint, in view: NSView)

他にもドラッグジェスチャーなどについても実装することが出来ます。

開発者名の指定

Info.plistPKWidgetAuthorに名前を指定することで実装できます。Widget設定画面に表示することが出来ます。
author.png

widgetの設定画面

作成したWidgetの設定画面を作ることも可能です。PKWidgetPreferenceプロトコルに準拠したViewControllerを作成し、Info.plistPKWidgetPreferenceClassに作成したクラス名を指定することで実装できます。

例として標準でインストールできるControlCenter widgetの設定画面は以下のようになっています。

スクリーンショット 2021-03-15 14.43.39.png

templeteでは例として以下のような設定画面を実装しています。

おわりに

最後までお読みいただきありがとうございました。
何か質問などありましたらTwitterやこの記事のコメント欄までお願いします。答えられる範囲ではありますがお答えさせて頂きます。

自分も以下のようなプラグインを作ってみました。気軽にタイム測定ができるので我ながら愛用しています。
このGitHubページからダウンロードできるので試してみてください。

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

swiftのMapKit(基礎)

フレームワークのインポート

   import MapKit

MKMapViewの生成

   //mapViewの生成
   let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
   self.view.addSubview(mapView)

MKMapViewの中心にピンを生成する

   let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
   self.view.addSubview(mapView)
   //緯度と軽度
   let location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(37, 140)
   var region: MKCoordinateRegion = mapView.region
   //表示するマップの中心座標を設定
   region.center = location
   //地図の拡大状態の設定
   //設定しないと地図の表示が最縮小される
   region.span.latitudeDelta = 0.5
   region.span.longitudeDelta = 0.5
   //regionに設定したマップの表示設定をmapViewに反映
   mapView.setRegion(region, animated: true)
   //マップのタイプ
   mapView.mapType = .hybridFlyover
   //マップのデリゲートの設定
   mapView.delegate = self
   //3Dの見え方の設定
   mapView.isPitchEnabled = true
   //ピン留めの生成
   let annotation = MKPointAnnotation()
   //どこにピンを設置するか
   annotation.coordinate = CLLocationCoordinate2DMake(location.latitude, location.longitude)
   annotation.title = "タイトル"
   annotation.subtitle = "サブタイトル"
   mapView.addAnnotation(annotation)

複数箇所のピン留め

   mapView.addAnnotations([annotation, annotation2, ...])

MKMapViewDelegate

   extension ViewController: MKMapViewDelegate {
       func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
           print("ピン留めが選択された時に呼ばれる")
       }

       func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
           print("ピン留めが選択解除になった時に呼ばれる")
       }

       func mapViewWillStartLoadingMap(_ mapView: MKMapView) {
           print("マップビューを読み込もうとしている時に呼ばれる")
       }

       func mapViewDidFinishLoadingMap(_ mapView: MKMapView) {
           print("マップビューが必要なマップデータを読み込んだ時に呼ばれる")
       }

       func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
           print("ユーザーの場所が更新された時に呼ばれる")
       }

       func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
           print("ひとつ以上のピン留めがマップに追加された時に呼ばれる")
       }
   }

MKMapViewのプロパティ

プロパティ名 説明
delegate MKMapViewDelegate デリゲートを指定
mapType MKMapType .standard: 標準の地図
.satellite: 航空写真
.hybrid: 標準の地図+航空写真
.satelliteFlyover: 3D航空写真
.hybridFlyover: 3D標準の地図+航空写真
isZoomEnabled Bool ズームできるかどうか
isScrollEnabled Bool 画面をスクロールできるかどうか
isRotateEnabled Bool マップが回転するかどうか
showCompass Bool コンパスを右上に表示するかどうか
showsTraffic Bool 交通情報を表示すかどうか
showsBuilding Bool 建物の名前を表示するかどうか
isUserLocationVisble Bool 現在の位置マップに表示されるかどうか
isPitchEnabled Bool 3Dに対応したmapType
region MKcoodinateRegion マップビューで現在表示されているエリア
camera MKMapCamera マップの外観を決定するために使用するカメラ
annotaions [MKAnnotaion] ピン留め
selectedAnnotations [MKAnnotation] 現在選択されているピン留め

MKMapViewのメソッド

メソッド名 説明
setCenter(MKCoordinateRegion, animated: Bool) regionに設定したマップの設定をMKMapViewに反映
addAnnotation(MKAnnotation) 指定したピン留めの追加
removeAnnotation(MKAnnotation) 指定したピン留めの消去
addAnnotations([MKAnnotation]) 複数のピン留めの追加
removeAnnotations([MKAnnotation]) 複数のピン留めの消去

MKMapViewDelegateメソッド

メソッド名 説明
mapViewWillStartLoadMap(MKMapView) マップビューを読み込もうとしたときに呼ばれる
mapViewDidFinishLoadingMap(MKMapView) マップビューが正常にロードした時に呼ばれる
mapView(MKMapView, didUpdate UserLocation: MKUserLocation) ユーザーの場所が更新された時に呼ばれる
mapView(MKMapView, didSelect view: MKAnnotationView) ピン留めが選択された時に呼ばれる
mapView(MKMapView, didDeselect: MKAnnotationView) ピン留めの一つが選択消去された時に呼ばれる
mapView(MKMapView, didAdd views: [MKAnnotationView]) 新しくピン留めがマップに追加された時に呼ばれる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む