なんとかするから、なんとかなる

エンジニア関係のことを書きます

iOS How to solve the build error related with "CommonCrypto" on Xcode10

Introduction

This article shows how to solve the build error related with "CommonCrypto" on Xcode10.

After updating the Xcode to version10, I faced on the error messages as below.

The CommonCrypto was imported by cocoapods in my case.

Redefinition of module "CommonCrypto"
error: could not build Objective-C module 'YOUR_MODULE'

Solution

Remove the "CommonCrypto" folder included in {YOUR_MODULE}.

It seems that the "CommonCypto" module is included in standard library on Xcode10.

How to connect to localhost on Mac from iPhone

Introduction

This article shows how to connect to localhost on Mac from iPhone and some tips.

Conditions

How to connect it

  1. Set up the localhost server on a mac
  2. Confirm the access to the "localhost:{PortNumber}" by safari or something.
  3. Check the mac's domain name from [Preference] - [sharing] ({YOUR_PC_NAME}.local) f:id:hopita:20180930154815p:plain
  4. Access the domain({YOUR_PC_NAME}.local) from iPhone by safari or something.

Finished!

Tips1

If the localhost uses the port number 80 or some another famous ports, the inbound request will be refused by mac native firewall.

To solve the problem, turn off the native firewall from [Preference] - [Security&Privacy].

But, as you know, it's not recommended.

Tips2

If you would like to connect the mac as API Server from iOS app, you need to turn off the ATS(App Transport Security) on the Xcode.

But, if you can access the server from https connect, it's not a problem.

Macで立てたlocalhostサーバーにiPhoneからアクセスする

English version below

はじめに

Macでテスト用サーバーを立ててiPhoneから簡易的に試したいときのTipsです。

前提

  • MaciPhoneは同一ネットワークに存在する

やりかた

  1. MacLocalhostサーバーを立てる
  2. localhost:{Port番号}でアクセスできることをsafariなどで確認する
  3. Mac [共有] からMacにアクセスするためのドメイン名を調べる({YOUR_PC_NAME}.local) f:id:hopita:20180930154815p:plain
  4. iPhonesafariなどで、ドメイン名({YOUR_PC_NAME}.local)にアクセス

完了です。

注意点1

Mac上のサーバーのポート番号に80番などよく使われるt番号を使用すると、MacFirewallにインバウンドを拒否されます。

回避方法としては、Mac [環境設定]-[セキュリティ&プライバシー] でFirewallをOFFにすればアクセスできますが、お勧めできません。

注意点2

iOSアプリのAPIサーバーとしてMaclocalhost サーバーを使用した場合、XcodeでATS(App Transport Security)をOFFにするのを忘れずに。

HTTPSでアクセスできる場合は問題無いです。

iOS Xcode10 で”CommonCrypto”のおかげでビルドエラーが出た時の対処法

English version below

はじめに

Xcode10来ましたね。

早速アップデートしてみると次のようなエラー。

CocoaPodsとかで、モジュールをプロジェクトに組み込んでいると出会いやすいっぽいです。

Redefinition of module "CommonCrypto"
error: could not build Objective-C module 'YOUR_MODULE'

読み進んでみると"CommonCrypto"が再定義されていると。

やったこと

1つ目

クリーンしてビルド

ー>失敗

2つ目

cocoapods pod update を実行

-> だめ

解決方法

対象のModuleに含まれる"CommonCrypto"フォルダを削除する。

どうやらCommonCryptoがXcode10から標準ライブラリに組み込まれるようになったらしいです。

その結果、既存のファイルとコンフリクトが発生、再定義とみなされるようです。

つらい。。。

iOS How to change a language settings while debugging on the devices

Introduction

This article shows how to change a language settings while debugging on the devices.

This method is useful for confirming the localized String or text including line breaks.

It won't need to change the language from settings anymore.

Solution

There are 2 steps for setting the language.

  1. [Open Edit scheme] f:id:hopita:20180910211338p:plain
  2. [Run]-[Application Language]-[System Language] and select a language you want to set. f:id:hopita:20180910211504p:plain

iOS 実機でデバッグするときに言語設定を変更する

English version is below.

はじめに

実機でデバッグ時に言語設定したい。

ローカライズがきちんとできているか、改行が正しくできているかなど確認するときに便利な方法です。

いちいちデバイス言語設定を変更する必要はありません。

解決方法

  1. Edit Schemeを開きます f:id:hopita:20180910211338p:plain
  2. [Run]のApplication Languageを"SystemLanguage"から好きな言語へ変更すればOKです。 f:id:hopita:20180910211504p:plain

iOS UIPageViewControllerで"Unbalanced calls to begin/end appearance transitions for" が出たときの対処方法

English version below

はじめに

UIPageViewControllerを早送りしたときに次のようなエラーが出ました。

Unbalanced calls to begin/end appearance transitions for 

そのときのコードはこんな感じです。

class MyPageViewController: UIPageViewController {
    var maxPage = 3
    var currentPage = 0

    ~~~~
    // SomeCode....
    ~~~~
}

extension MyPageViewController: UIPageViewControllerDataSource {
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard self.currentPage > self.maxPage else { return nil }
        self.currentPage += 1
        
        let myAfterVC = MyAfterViewController()
        
        return myAfterVC
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard self.currentPage >=  0 else { return nil }
        self.currentPage -= 1
        
        let myBeforeVC = MyBeforeViewController()
        
        return myBeforeVC
    }
}

原因

このエラーメッセージは、現在のUIViewControllerの表示が完了する前に、次のUIViewControllerへ遷移しようとしたときに出るようです。

解決方法

遷移中に再度遷移しないようにフラグをもたせました。

UIPageViewControllerDelegateを通して、で遷移の開始と終了を知ることができます。

したがって、コードでは次のようになります。

class MyPageViewController: UIPageViewController {
    var isTransitioning = false
    var maxPage = 3
    var currentPage = 0

    ~~~~
    // SomeCode....
    ~~~~
}

extension MyPageViewController: UIPageViewControllerDataSource {
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard self.currentPage < self.maxPage, self.isTransitioning == false else { return nil }
        self.currentPage += 1
        
        let myAfterVC = MyAfterViewController()
        
        return myAfterVC
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard self.currentPage >=  0, self.isTransitioning == false else { return nil }
        self.currentPage -= 1
        
        let myBeforeVC = MyBeforeViewController()
        
        return myBeforeVC
    }
}

extension MyPageViewController: UIPageViewControllerDelegate {
    func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
        self.isTransitioning = true
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        self.isTransitioning = false
    }
}