20200621のSwiftに関する記事は5件です。

実機テストで「The maximum number of apps for free development profiles has been reached.」のエラーが出て困った話。

カメラアプリの開発中、実機にてビルドを行うと「Unable to install "product name"」と出てきて、詳細を確認すると「The maximum number of apps for free development profiles has been reached.」のエラーが出て、実機にアプリのインストールができず困った話です。

実行環境
xcode:version 11.5
iOSバージョン:13.5.1
実機:iphone7 

お金を払って開発者アカウントにしない限り、xcodeで作成したアプリを実機に三つまでしかインストールできないとのことだったのですが、私は初めての実機テストだったためインストールしているアプリが0の状態で、エラーが発生していました。

上記のような状況で、私が解決できた方法について以下に記載いたします。

1.Window->Devices and Simulators->実機を選択してOpen Consoleボタンをクリックしてログを表示
2.アプリを実行して実機へのインストールを試みる。
3.右上の検索にMIFreeProfileValidatedAppTrackerを入力してログを絞り込む。

コンソールログのコピー.png

ログメッセージを確認すると、AppStoreから以前ダウンロードしたであろうアプリが表示されます。ここに表示されているアプリは、以下の写真のように実機ホーム画面の雲マークがついたアプリになるかと思います。

iphoneホーム画面.PNG

雲マークがついたアプリをインストールもしくは削除することで、今回のエラーは解消されました。

「非使用のAppを取り除く」という設定をONにしていると、長期間使用されていないアプリが削除され、雲マークがつくようです。

xcodeのアプリが問題ではなく、AppStoreのアプリ原因だったのは盲点で、かつ実機のログまで確認しないとエラーの原因にたどり着かないので、教えていただいた方には本当に感謝しております。

似たような状況の方の解決につながれば幸いです。

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

try do catch構文について

try do catchについて理解を得たのでまとめ
まずはコードから

enum HogeError: Error {
    case hoge
    case hogehoge
    case hogehogehoge
}

class Hoge {
    class func hoge() throws -> String {
        if !false {
            throw HogeError.hogehogehoge
        }
        return "成功"
    }
}

class Hogehoge {
    class func hoge() -> String {
        do {
            _ = try Hoge.hoge()
        } catch HogeError.hoge {
            return "hoge"
        } catch HogeError.hogehoge {
            return "hogehoge"
        } catch HogeError.hogehogehoge {
            return "hogehogehoge"
        } catch {
            return "来ない"
        }
        return "成功"
    }
}

・エラーハンドリング(HogeError)を列挙型で定義(プロトコルErrorに準拠させる)
・Hogeクラスのhogeメソッドはエラーを投げているのでメソッドに「throws」を書く必要がある(エラーを投げていると明示するため)
・Hogehogeクラスのhogeメソッドでdo catch構文を実装
・doで実装しエラーが返ってきたらcatchでエラー実装をする(ログを出すなど)
・エラー処理を複数実装することができる(最後のcatchは来ないが実装必須)

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

ネストループをラベルで指定して抜ける方法

struct Hoge {
    let test: [String]
    let test1: [String]
}

let hoge = Hoge.init(test: ["3","3","3","4","3","3"] , test1: ["3","3","3","4","3","3"])

outer: for i in hoge.test {
    inner: for t in hoge.test1 {
        if i == t {
            print("inner")
            break inner
        } else {
            print("outer")
            break outer
        }
    }
}
inner
inner
inner
outer

for文の前にラベルをつけることで抜ける際にどのループ文を抜けるのか指定することができる。
While文やswitch文でも使うことはできる。

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

【プログラミング初心者】Swift基礎~アクセス修飾子~

はじめに

今回はオブジェクト指向の考え方の1つであるカプセル化を実現するためのアクセス修飾子の使い方について紹介します。
カプセル化がどういうものかはこちらで紹介しているので参照してください。

アクセス修飾子

アクセス修飾子はそのプロパティもしくはメソッドを外から呼べるかどうかの権限を表します。
これは定義の頭に付けるもので構文は以下となります。

アクセス修飾子構文
// プロパティの場合
アクセス修飾子 var 変数: 

// メソッドの場合
アクセス修飾子 func メソッド名() {

}

見ればわかるようにいつもの定義の仕方の頭にアクセス修飾子を付けるだけですね。

Swiftのアクセス修飾子は以下の5種類があります。
上から順に制約はゆるくなります。

アクセス修飾子 概要
private クラス内からしかアクセスできない
fileprivate 同じファイル内からしかアクセスできない
internal 同じモジュール内からはどこからでもアクセスできる
public 他のモジュールからもアクセスできるがオーバーライドできない
open 他のモジュールからもアクセスでき、オーバーライドできる

よく使うのはprivateinternalになるかと思います。
この2つについて具体的な実装を紹介します。

private

最も厳しいアクセス修飾子でクラス内でしか呼び出せないプロパティ、メソッドに付けます。

class MyClass {
    private var privateProperty = 0

    private func privateMethod() {
        print("privateMethod")
    }

    func testMethod() {
        self.privateMethod() // OK
        let tmp = self.privateProperty // OK
    }
}

let myClass = MyClass()
myClass.privateMethod()  // NG
let tmp = myClass.privateProperty // NG

noPrivateMethod()での呼び出しのようにクラス内で扱う時は特に気にする必要はありません。
クラスの外から呼び出そうとすると
'privateMethod' is inaccessible due to 'private' protection level
'privateProperty' is inaccessible due to 'private' protection level
というように怒られます。
※そもそもprivateで指定したメソッド、プロパティは補完候補にも挙がってきません。

internal

「同じモジュール内からはどこからでもアクセスできる」と説明しています。
モジュールとありますが今はそれほど意識しなくても構いません。
アプリ内であればどこからでもアクセスできるととりあえずは覚えてください。

またアクセス修飾子なしでメソッド、プロパティを定義するとinternalとして扱われます。
そのため自分でinternalと指定することはあまりないかと思います。

以下実装例です。

class MyClass {
    internal var privateProperty1 = 0
    var privateProperty2 = 0

    internal func internalMethod1() {
        print("internalMethod1")
    }

    func internalMethod2() {
        print("internalMethod1")
    }

    func testMethod() {
        self.internalMethod1() // OK
        self.internalMethod2() // OK
        let tmp1 = self.privateProperty1 // OK
        let tmp2 = self.privateProperty2 // OK
    }
}

let myClass = MyClass()
myClass.internalMethod1() // OK
myClass.internalMethod2() // OK
let tmp1 = myClass.privateProperty1 // OK
let tmp2 = myClass.privateProperty2 // OK

このように外から参照できるものは今まで通り何も付けない or internalを付けると覚えましょう。

private(set)

プロパティに関しては外から変えられたくないが参照はできるというものもあります。
readonlyプロパティなどと言ったりします。
このときのアクセス修飾子はprivate(set)を使用します。

以下実装例です。

class MyClass {
    private(set) var readOnlyProperty = 0

    func testMethod() {
        let tmp = self.readOnlyProperty // OK
        self.readOnlyProperty = 1 // OK
    }
}

let myClass = MyClass()
let tmp = myClass.readOnlyProperty // OK
myClass.readOnlyProperty = 1 // NG

myClass.readOnlyProperty = 1とすると
Cannot assign to property: 'readOnlyProperty' setter is inaccessible
と怒られます。

最後に

今回はカプセル化を実現するためのアクセス修飾子について紹介しました。
それほど難しい内容ではないかなと思うのでこの機会に覚えておきましょう。
もちろんどれを公開してどれを非公開にするかの判断には多少の経験がいるかとは思いますが。

今回の内容は以上です。
本記事とは別でプログラミング未経験からiOSアプリ開発が行えるようになることを目的とした記事を連載しています。
連載は以下にまとめていますのでそちらも是非もご覧ください。
アジェンダ:https://qiita.com/euJcIKfcqwnzDui/items/0b480e96166e88945684

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

構造体とクラスの違いについてのメモ

Swift初心者が構造体とクラスについて、理解できた事をメモしました。間違えていたら、ご指摘ください。

構造体とクラスの違い

構造体とクラスはとてもよく似ていて分からなかったのですが、調べていくと結構違いがありました。

①継承

継承する事で他のオブジェクトの機能をほぼ引き継ぎ、使用することができます。

  クラス・・・他のクラスを継承できる

  構造体・・・他の構造体を継承できない

class a {
    var b : Int
    init() {
        b = 10
    }
}

struct c {
    var d : Int
    init() {
        d = 10
    }
}

//クラスaを継承
//但し、親クラスのイニシャライザの継承は、基本的にはしないようです
class z : a {
    override init() {
    }
}

//構造体cを継承、エラー
struct q : c {     
    override init(){        
    }
}

②型

参照型か値型かによって、インスタンス化する際に定数・変数のどちらを使うかで、格納されているプロパティを書き換えできたり、できなかったりします。

  クラス・・・参照型  変数・定数どちらでも書き換え可能

  構造体・・・値型   変数のみ書き換え可能

//クラスの場合
class a {
    var b : Int
    init() {
        b = 10
    }
}
//インスタンス化
let e = a()

//10が出力される
print(e.b)

//20が出力される
e.b = 20
print(e.b)


//構造体の場合
struct c {
    var d : Int
    init() {
        d = 10
    }
}
//インスタンス化 ここをvarに変えれば下記のエラーは出ないです
let f = c()

//10が出力される
print(f.d)

//ここでエラーが出ます
f.d = 20
print(f.d)


  

因みに、プロトコルの採用はクラス、構造体のどちらでもできます。まあ、共通の規則を構造体全てに一から書いていくのも、合理的ではないですしね。ただ、クラスの継承も、プロトコルの採用も同じような場所に書くから、多少ややこしいです。最初は構造体でも継承できるのかなって思っていました。

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