徒然エンジニアブログ

徒然エンジニアブログ

理系東大生がプログラミングを中心に様々なことについて情報発信していきます!

【Swift】Firebaseを使ったiOSアプリの開発〜ユーザー認証〜

FirebaseはGoogleが提供しているサービスで,メールやパスワードを使ったログイン機能、リアルタイムデータベース、さらには画像などを保存するストレージなど様々な機能を使うことができます。


前回の記事でFirebaseをiOSアプリを作るための設定をしたのでいよいよ使って行きたいと思います。
読んでいない人はまずこちらからどうぞ!
turedureengineer.hatenablog.com


今回はFirebaseを用いてユーザー認証をしていく方法について解説して行きたいと思います。
ユーザー登録したり、認証してログインなどというのは難しそうに思えますがFirebaseを使うと簡単にできます。

それではみて行きましょう。

ログイン方法を設定する

まずFirebaseコンソールの画面に行きます。
そして左側から「Authentication」を押します。

すると下のようなところに飛ぶので「ログイン方法を設定」というところをクリックします。
f:id:turedureengineer:20190106194220p:plain

すると下のような画面になると思います。
みてわかる通りログイン方法といってもいろいろあります。
メールアドレスとパスワードでログインするオーソドックスなものから、最近増えてきているFacebookTwitterを使ったものなど様々な方法があります。


今回はメールとパスワードを用いたものを使って行きましょう!
f:id:turedureengineer:20190106194342p:plain

「メール/パスワード」というところをクリックすると以下のような画面になるので上のチェックボタンを有効にしてください。
そして保存してください。


下のメールリンクというところは向こうのままで構いません。
f:id:turedureengineer:20190106194728p:plain

ユーザーの新規作成の方法

コードを書いていくときに注意ですがFirebase関連のコードを書くときは必ずそのファイルの先頭にimport Firebaseを書いておきましょう!


以下のコードでできます。
非常に短いですね。さすがFirebaseといったところです。

Auth.auth().createUser(withEmail: "a@gmail.com", password: "abcdef",completion: {(user, error) in
            //エラー処理
            if error != nil{
                print(error!)
                return
            }
            //成功した時
            
})

メールアドレスやパスワードは今回は例なので直で書いちゃってますがもちろん実際のコードではテキストフィールドのものを変数に読み込むなどして変数を書いておいてください。


completion以下が少し見慣れない形ですがここはそれに続く処理を書いておけばいいだけです。


エラーの場合はerrorの中にその内容が入っているので場合分けをして出力させるようにしています。

例えばですが、メールアドレスを"abc"とかにするとエラーが出ます。練習として使う場合は上のように"~@gmail.com"や"~@docomo.ne.jp"としておけばいいです。
実在かどうかは気にしなくていいです。

新規作成に成功したときにそのままログインさせたい時などはその処理を//成功したときというところの下に書けばおっけいです!

うまくユーザーの新規作成に成功するとAuthenticationの画面でこのように見えます。
f:id:turedureengineer:20190106233538p:plain

ログイン方法

これも簡単です。

Auth.auth().signIn(withEmail: "a@docomo.ne.jp", password: "abcdef",completion: {(result, error) in
            //エラー処理
            if error != nil{
                print(error!)
                return
            }
            //成功した時
})

形は新規作成するときとほとんど同じです。
さっきと同じ注意ですがメールアドレスやパスワードには変数のものにしておいてください。
上のものはあくまで例です。

【Swift】Firebaseを使ったiOSアプリの開発〜初期設定の手順〜

FirebaseはGoogleが提供しているサービスです。


メールやパスワードを使ったログイン機能、リアルタイムデータベース、さらには画像などを保存するストレージなど様々な機能がついています。


驚くことにこれらの全てを無料で使えます!


もちろん無料だとデータ量などに制限はありますが。


ログイン機能があるアプリを使いたい人にはオススメです!


今回はFirebaseでIOSアプリを使いたいと思ってる人向けに初期設定のことについて説明して行きたいと思います!

xcodeプロジェクトの作成

まずはじめにxcodeプロジェクトを作成します。


「Single View APP」を選択します。
名前は適当でいいです。今回は「FirebaseSample」としました。
languageはSwiftを選択し、下三つのチェックは全て外しておいてください。

Firebaseでプロジェクトを作成

Firebaseのコンソール画面に移動します。
https://console.firebase.google.com

グーグルアカウントの登録などを求められたらしておいてください。
f:id:turedureengineer:20190104012500p:plain

ここの「プロジェクトを追加」というところを押します。
すると下のような画面になると思います。
f:id:turedureengineer:20190104012504p:plain

プロジェクトの名前はここではSampleとしていますがなんでもいいです。
Xcodeプロジェクトと同じ名前にしておくといいかもしれません。


プロジェクトの名前を決めると自動でプロジェクトIDが決まります。


地域は上の画像ではアメリカのままですが日本にしておきましょう。


下二つのところにチェックを入れてプロジェクトを作成というところを押しましょう。

これでFirebaseでのプロジェクトの作成は完了です。

iOSアプリで使うための設定

Firebaseでのプロジェクトの作成が完了すると、下のようなページに移動します。

f:id:turedureengineer:20190104174001p:plain

次にiOSアプリでFirebaseを使うための設定をして行きます。
上の画像にあるようにiOSというところをクリックします。


すると下のような画面になります。
f:id:turedureengineer:20190104012410p:plain


手順が詳しく書いてあるのでここからは補足をして行きます。
iOSのバンドルIDというところは下の画像の赤いところを押すと出てきます。
f:id:turedureengineer:20190104020741p:plain
f:id:turedureengineer:20190104020744p:plain

これをコピーしてFirebaseの方に貼り付けます。


次のファイルのダウンロードはわかりやすいと思います。


三つ目のFirebaseSDKの追加というのはターミナルで行う必要があるため少し難しいかもしれません。
移動とかがわからない人は下の記事を見てみてください。
turedureengineer.hatenablog.com
turedureengineer.hatenablog.com

pod 'Firebase/Core'

をPodfileに加えるとありますが、これだけでは認証もリアルタイムデータベースもストレージも使うことができません。


それぞれ個別にpodをインストールする必要があります。

pod 'Firebase/Database'
pod 'Firebase/Auth'
pod 'Firebase/Storage'
pod 'Firebase/Core'

この四つを加えておきましょう。
そして

$pod install

とします。


そして初期化コードを書くとありますがこれは拡張子がxcodeprojのものではなく、xcworkspaceのものを開いて書く必要があります。
xcodeprojの方に「import Firebase」などと書いてもエラーが出ます。


これで初期設定は全て終了です。
次回からは具体的にどのように使っていくかやって行きたいと思います。

turedureengineer.hatenablog.com

【ブログ月次報告】【5ヶ月目】pv数が倍以上に!!

ブログ報告5ヶ月目ということでやって行きましょう!

まずはじめにブログを始めて5ヶ月と言いましたが、はじめの4ヶ月はのんびり気が向いたら投稿するという感じでトータルで6記事ほどしか書いていませんw


12月は始めて本格的にブログを始めました。
そんな5ヶ月目でしたがpv数などはどうなったでしょう??

現在の状況

  • 読者数 5→15
  • ユーザー数 26→115
  • pv数 46→316
  • 記事数 14→34

左側が4ヶ月の時点での数字です。


先月の末に立てた目標は

  • 読者数 10
  • ユーザー数 50
  • pv数 100
  • 記事数 14→30

こんな感じでした。


全ての目標を達成できました!!
pv数、ユーザー数共に倍以上に伸びました。


一番大きな要因は単純に書いた記事数が多かったことだと思います。
毎日ブログを書くことは大変だけど効果は確実にありますね。
一月の目標は下に書きますが、できるだけ多くの記事を書きたいと思います。


読者数は目標は10でしたが15まで増えました。
拙いブログですが見てくれている人本当にありがとうございますw
今月はブログについての記事を多く出したことも読者数が増えた一因かと思います。

アクセス元の割合

はてなブログGoogle検索の割合が増えました。


内部リンクを増やしたことや、はてなブログをしている人向けの記事を書いたことがはてなブログからの割合の増加につながったと思います。


Google検索の割合が増えてきたのはいい感じですね。
プログラミングで困った時とかに検索してこのブログが出てくるようになることが狙いなので。

特に以下の記事は「Unity public」と検索すると7番目に出てきて一番検索流入を稼いでくれています。
turedureengineer.hatenablog.com


これは自分がつまづいたところを記事にしたものです。
やっぱりみんながつまづくところをわかりやすく説明して記事にすると検索順位は上がってきますね。

にほんブログ村に登録した

色々なところから集客した方がいいのかなと思い、にほんブログ村に登録しました。
検索流入は一番多い時で2%くらいでした。

はてなブログはがてなブログ内での繋がりが深いので無理に登録する必要はなかったかもしれません。

6ヶ月目の目標

  • 読者数 20
  • ユーザー数 200
  • pv数 500
  • 記事数 34→45

これが次の月の目標です!
今月結構伸びたのでやや高めに目標を設定しました。


しかし来月は今月ほど記事を書けないことが予想されるので心配ではあります。
そんな中でもなんとか時間を作って11記事更新を目指して行きたいと思います。


読者登録等のびるとやる気が出るのでぜひ登録お願いします!

【Unity】物体を移動させる方法3つを紹介!!

今回はUnityをやっていると絶対にぶつかる物体の移動のさせ方について解説していきたいと思います。

transform.position

まず一つ目は直接transform.positionの値を変更するやり方です。

this.gameObject.transform.position = new Vector3(3,3,3);

このように使って指定の位置に移動させます。
ゲームの開始時になどに指定の位置に置くために使うことなどが多いです。


これをうまく使うと少しずつ移動して動いているように見せることができます。

void Update()
{
    //現在の位置を取得
    Vector3 pos = this.gameObject.transform.position;
    //現在の位置からx方向に1移動する
    this.gameObject.transform.position = new Vector3(pos.x+1,pos.y,pos.z);
}

このように現在の位置を取得してそれを元に1ずつ移動するというのを毎フレームごとに行います。
すると動いてるように見えるというわけです。


transform.positionで取得することができるのはワールド座標です。
これに対してローカル座標というものがあります。


これを取得するときにはtransform.localPositionを使えばいいだけです。


ローカル座標とワールド座標については以下の記事で詳しく説明しています。
turedureengineer.hatenablog.com

transform.Translate

次にtransform.Translateを使って移動させる方法です。

void Update(){
    this.gameObject.transform.Translate(1,1,1);
}

transform.Translateは現在の位置からどれだけ移動するかというものです。
上のように書くと毎フレームごとにx,y,z全ての方向に1ずつ動きます。


transform.Translate自体が現在位置からどれだけ移動するかというものなので先ほどのように現在位置を取得したりする必要はありません。


物体を動かすならこちらの方がわかりやすいですね。

AddForce

これは今までのものとは違いRigidbodyを使って移動させるものです。

そのためまずはRigidbodyを付け加える必要があります。
インスペクタの下のとことに「Add Component」というのがあります。ここを押して「Physics」→「Rigidbody」とすると設定できます。

void Start()
{
    rb = GetComponent<Rigidbody>();
}
void Update()
{
    rb.AddForce(1,1,1);
}

こうするとx,y,z方向に1ずつの力を加えることになります。


今回の例で言えばUpdate関数の中で毎回力を加えることになってしまうので、どんどん加速して行きます。
力を加えるのは一回だけでいいならStart関数の中で力を加えます。


Rigidbodyを使うことに利点はUnityに物理演算を任せることができるという点です。

そのため力を加えるだけでそのあとの移動はUnityが自動で計算してくれます。

特に衝突などを利用したい場合はこれを使うべきです。
なぜならtransform.positionなどを利用して動かすと衝突するべきところもすり抜けてしまうことがあるからです。

【Unity】ワールド座標とローカル座標の違い!

今回は初心者が混同しやすいワールド座標とローカル座標について説明したいと思います。

ワールド座標とは?

ワールド座標とはシーン上の(0,0,0)を中心にした座標のことです。
ただ単にシーン上にオブジェクトを置くとインスペクタ上に座標が書いてありますがこれはワールド座標です。

ローカル座標とは?

ローカル座標とは親オブジェクトからの相対位置のことです。


例えば親オブジェクトのワールド座標が(1,2,3)で子オブジェクトのワールド座標が(4,2,1)だったとします。
このとき子オブジェクトのローカル座標は(3,0,-2)となります。
ベクトルの引き算というわけですね。


また親を持たないオブジェクトの場合インスペクタ上に表示される座標はワールド座標ですが、子オブジェクトの場合ローカル座標が表示されます。

実際の例

以下のようにcubeのこオブジェクトとしてsphereを作った時を見てみましょう。
ヒエラルキーは下のようになります。
f:id:turedureengineer:20181229142428p:plain

この時親オブジェクトであるcubeの表示される座標はワールド座標で以下のようになります。
f:id:turedureengineer:20181229142529p:plain

これをみてわかる通りcubeのワールド座標は(1,0,0)です。
ではこの時の子オブジェクトを見てみましょう。
f:id:turedureengineer:20181229142957p:plain

先ほどでも言いましたがここでの(0,0,0)は親オブジェクトに対して(0,0,0)ということです。


つまり今回の例では子オブジェクトは親オブジェクトからずれていないということです。

【Swift】アプリ開発初心者の私が1ヶ月でアプリを作れるようになったオススメの勉強法

今回は私がアプリを作れるようになるまでにしたことを全部話して行きたいと思います。


iPhoneアプリを作ってみたいけど何をしたらよいかわからないという人はぜひ参考にしてみてください。
一度挫折して諦めた時期もあるので今つまづいてる人は特に参考になるかもしれませんw

時系列でやったことを書いて行きたいと思います。

アプリを作ろうと思った時のプログラミング経験

一番最初にSwiftでアプリを作ろうと思った時は大学の授業でC言語Pythonをやったことがある程度でした。
C言語でターミナルで遊べるオセロを作ったりしていました。

一番最初に買った本

そんな中プログラミングを用いて何かを作ってみたいということでアプリを作ろうと思いました。
Swiftはやったことがないので本を買って勉強することになりました。

その時に買った本がこちらです。

iPhoneアプリ開発講座 はじめてのSwift

iPhoneアプリ開発講座 はじめてのSwift

この本は全編カラーでXcodeのインストールの方法から、Swiftの文法の解説、最後には模擬アプリの作り方まで載っていてとても役に立ちました。

全ページカラーで画面のスクリーンショットなども豊富に乗っているので初心者の方にはよりオススメできます!

クラスという概念で挫折

先ほど書いたようにプログラミング自体は結構やっていたので序盤の変数や配列などは軽くクリアできました。
オプショナルなどはSwiftに特有のもので最初こそ戸惑いましたが何回も説明を読み実際にコードを書いてみることでなんとか理解しました。


つまずいたのはクラスの概念です。
C言語にはクラスという考え方はありません。PythonにはありますがPythonC言語ほどはやっていないためつまづいてしまいました。


それでも何度か読むうちに継承などの部分部分は理解できました。
しかしながらクラスという考えをアプリを作る時にどのように活かすのかがわかりませんでした。
ここで一旦アプリの開発を断念しましたw

Unityでクラスの概念を理解した!

一旦Swiftを諦めた私ですがこの頃新たにUnityでゲームを作り始めました。

Unityにももちろんクラスという考えはあります。
しかしゲームで実際の動きが見てわかるということもありUnityでゲームを作ることを通してクラスというものを理解して行きました。

皆さんももしクラスという考えに戸惑ったらunityをしてみるのもいいかもしれませんw

もう一度Swiftで青売りを作ろうと決心する

クラスの概念を学んだ私はもう一度Swiftを学びなおそうとしました。

前と同じ本でもいいのですがより詳しいものでより深く勉強したいと思い別の本を買うことにしました。
それがこちらの本です。

この本は先ほど紹介したものよりは上級編という感じでとにかくいろいろ乗っています。
今でも何かあったらこれを見てみるほどです。

このように辞書のような使い方もできるのでオススメです。

実際にアプリを作ってみる

一番最初に紹介した本にも模擬アプリは乗っていますが比較的簡単なものが多かったです。
本格的なものを一回作ってみたいと思いyoutubeで勉強することにしました。
その時使ったのがこちらです。


Swift: Firebase 3 - How to Build a Login Page Using iOS9 Constraint Anchors (Ep 1)


この動画はFirebaseを用いてチャットアプリを作るというものです。
ログイン機能などもある本格的なものです。

全25回あって一つ一つも30~60分あるので終わらせるのは結構しんどいですがかなりの力がつきます。
一部今と違う書き方とかも出てきましたがググれば出てきます。

私がstoryboardを使わなくなったのもこの動画の影響ですw
こちらの記事に詳しく書いてあるのでみてみてください。
turedureengineer.hatenablog.com

これをみながらアプリを作った後はもう大体のものは作れるようになりました。

終わりに

今回私がアプリを作れるようになるまでにしたことを全部書いてきました。
ぜひ一度アプリ開発につまずいた人やこれから作ってみたい人は頑張って行きましょう!

【Swift】配列の基本から応用〜これさえわかればSwiftの配列は完璧!!〜

多くのプログラミング言語と同様に、Swiftにも配列という概念があります。

配列とは変数をまとめる機能のことです。
Int型、String型など多くの方の変数をまとめて扱うことができます。


もちろんアプリを開発するときにも多く使われます。
今回はそんな配列の基礎から応用までを一気に紹介したいと思います。

配列の初期化

まずは一番初めなので配列を作るところから始めます。

//値を入れて配列を作る
let numbers = [0,1,2]

//値を入れずに配列を作る
var stringArray:[Int] = []
var doubleArray:Array<Double> = []
var doublenumbers = [Double]()

配列を作るときには初めから値を入れておく方法と、とりあえず配列だけ作って後から変数を入れておく方法との二種類があります。
後から値を入れる場合の時は必ずvarで宣言しておいてください。そうしないと追加することができません。


また初めから値を入れる場合は入れた値の型を自動で判別してくれるので型を明記する必要はありません。
後から入れる場合は必ずどの型かわかるように2 ~4行目のように書く必要があります。
この書き方はどちらでも構いません。


また配列は最初に言ったように複数の値をまとめて扱うためのものです。
そのため変数名は例のように複数形やArrayz~という場合が多いです。
こうしておくと名前を見ただけでこれは配列だとわかるからです。

配列の特徴を知りたい時

配列の要素の数を取得する

配列の要素の数を知りたい時は以下のコードで取得することができます。

let numbers = [0,1,2]
print(numbers.count)

こうすると3と出力されます。
配列の要素数は(配列の名前).countで取得できます。

配列が空かどうか判定する

let numbers = [0,1,2]
//falseとprintされる
print(numbers.isEmpty)

配列が空だとtrue、空じゃない時はfalseになります。

配列の要素にアクセスする

任意の要素にアクセス

let numbers = [0,1,2]
//2番目の要素である2が出力される
print(numbers[2])

プログラミングを過去にやったことがある人には常識かもしれませんが、配列の要素の最初は0から始まることに注意してください。


この時要素がないところにアクセスしようとするとエラーになるので気をつけてください。
要素の数を3にした時、三番目の要素はないので気をつけてください。これは先ほども言ったように最初の要素を0番目のものとするからです。

一番最初の要素にアクセス

let numbers = [0,1,2]
//最初の要素である0が出力される
print(numbers.first!)

(配列の名前).firstで配列の一番最初の要素にアクセスすることができます。
ただし気をつけばければならないのはこれで取得できるのはオプショナル型だということです。

そこで今回はfirstの後に!をつけてアンラップしています。

一番最後の要素にアクセス

let numbers = [0,1,2]
//最後の要素である2が出力される
print(numbers.last!)

これはfirstの時とほぼ同じなので解説は省きます。

ランダムに要素にアクセス

ランダムに要素にアクセスするには以下のようにします。

let numbers = [0,1,2]
//ランダムで0か1か2が出力される
print(numbers.randomElement()!)

これも先ほどと同様にオプショナル型になっています。
そこで必要に応じてアンラップする必要があります。

配列の要素を追加する

配列の最後に付け加える

var number:[Int] = [0,1,2]
number.append(3)
//[0, 1, 2, 3]が出力される
print(number)

このように(配列の名前).append(追加したい値)として使います。
元の配列がInt型であった場合String型などの他の型の値を追加しようとするとエラーになるので気をつけてください。

任意の場所に追加する

先ほどのappendは最後に追加することしかできませんでした。
任意の場所に追加痛い時は以下のようにします。

var number:[Int] = [0,1,2]
number.insert(3, at: 1)
//[0, 3, 1, 2]と出力される
print(number)

(配列の名前).insert(追加したい値,追加したい場所の番号)とします。
この時追加したところより後ろの数は番号が変わることに注意してください。

配列の要素を削除する

任意の場所の要素を削除

任意の要素を削除したい時は以下のようにします。

var number:[String] = ["A","B","C"]
number.remove(at: 1)
//["A", "C"]と出力される
print(number)

このように場所を指定することで任意の場所の要素を消すことができます。

最初の要素を削除

最初の要素を削除したい時は以下のようにします。

var alphabets:[String] = ["A","B","C"]
alphabets.removeFirst()
//["B", "C"]と出力される
print(alphabets)

これは単純に一番最初の要素を消すだけです。

これの応用として

alphabets.removeFirst(2)

とすると最初から二つ分の要素を消すことができます。

最後の要素を削除

最後の要素を削除したい時は以下のようにします。

var alphabets:[String] = ["A","B","C"]
alphabets.removeLast()
//["A", "B"]と出力される
print(alphabets)

これも応用として

alphabets.removeLast(2)

とすることで最後から二つ分の要素を消すことができます。

全ての要素を削除

全ての要素を削除したい時は以下のようにします。

var alphabets:[String] = ["A","B","C"]
alphabets.removeAll()
//[]と出力される
print(alphabets)

配列の要素を消すだけで配列そのものは無くならないということに注意してください。