- 投稿日:2021-01-20T23:12:55+09:00
[Swift] UIButtonクラスをコードで作る
UIButtonクラスを作る
ボタンはUIButtonクラスなので、インスタンスでボタンを作れます。
準備
上の画像をAssetsフォルダの中に入れます。
これで準備完了です。やってみる
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() //ボタンを作る let okButton=UIButton() //領域とボタンの位置 okButton.frame=CGRect(x:100,y:100,width: 120,height: 120) //背景画像 let bkgImage=UIImage(named: "maru.png") okButton.setBackgroundImage(bkgImage, for: .normal) view.addSubview(okButton) } }まず、UIButtonのインスタンスをokButtonに格納します。
そして、ボタンの位置とサイズをCGRect型で決定します。
背景画像をUIImage型で読み込んで,setBackgroundImageメソッドの引数に値を渡します。最後に、
view.addSubView
メソッドの引数にokButtonを渡します。
これは、viewにボタンを表示するためのメソッドです。
- 投稿日:2021-01-20T23:03:07+09:00
SwiftyTesseractとOpenCVを入れたら「duplicate symbol」しまくった話
タイトルの通り。
duplicate symbol
が出まくって面を食らったので解決策を備忘録として残しておきます。環境情報
名前 バージョン Xcode 12.3 (12C33) Swift 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28) SwiftyTesseract 4.0.0 CMake 3.19.3 Python 2.7.16 xcode-select 2384 OpenCV 4.5.1 SwiftyTesseractとOpenCVを同じプロジェクトで使う
二つを同じプロジェクトで使うための手順を示します。
SwiftyTesseractをプロジェクトに追加する
2021年1月19日現在、SwiftyTesseractはSwift Package Managerからしか追加できませんので、Swift Package Managerから追加します。
Xcode上で「File > Swift Packages > Add Package Dependency...」と選択して、
入力欄に以下のGitHubのURLを入力します。https://github.com/SwiftyTesseract/SwiftyTesseractOpenCVをプロジェクトに追加する
iOS用にビルドする
GitHubからOpenCVを入手して、
platform/ios/
にある以下のコマンドでiOS用にビルドします。$ ./platform/ios/build_framework.py <output_dir>
ビルドしたframeworkファイルをプロジェクトに追加する
プロジェクトファイルを選んで、左ペインの「TARGETS」からアプリを選択します。
そして「Build Phases > Link Binary With Libraries (n items)」と選択して、ビルドで出力された「opencv2.framework」をドラッグ&ドロップなどで追加します。
Other Linker Flagsに
-all_load
を追加するプロジェクトファイルを選んで、左ペインの「PROJECT」からアプリを選択します。
「Build Settings」を選択して、「Linking > Other Linker Flags」に-all_load
を追加します。
libc++.tbdをプロジェクトに追加する
同じくプロジェクトファイルの「TARGETS」からアプリを選択します。
そして「General > Frameworks, Libraries, and Embedded Content」と選択して、左下の「+」ボタンを押します。
検索窓に「libc++」と入力すると「libc++.tbd」が出てくると思うのでそれを追加します。
試しにビルドしてみるが…
試しにビルドしてもこの時点ではうまくいきません。エラーを見ると「509 duplicate symbols for architecture x86_64(シミュレータなら×86_64、実機ならarm64)」というものすごい数の競合が起きていることがわかります。
解決方法ですが、opencv2.frameworkから競合が起きているファイルを削除することで解消できます。競合が起きているファイル(.oファイル)をまとめる
エラーを頼りに競合が起きてるファイルをまとめます。執筆者の環境では以下のファイル内で競合が起きていました。
jutils.o pngrio.o pngwio.o jdcoefct.o jaricom.o jdmainct.o jdcolor.o pngerror.o jfdctint.o pngget.o pngrutil.o jmemmgr.o jccoefct.o jcmaster.o jidctflt.o pngpread.o jcprepct.o jerror.o pngset.o jctrans.o jcparam.o jdinput.o pngwtran.o jdarith.o jdsample.o jcomapi.o png.o pngrtran.o jchuff.o jddctmgr.o jidctfst.o jfdctfst.o pngwrite.o jfdctflt.o jdatasrc.o jdapistd.o pngmem.o jdapimin.o pngwutil.o jcdctmgr.o jdtrans.o jdhuff.o jdmaster.o jcapistd.o jdatadst.o jquant2.o jdmerge.o jmemnobs.o jccolor.o jdmarker.o jdpostct.o jcmarker.o jidctred.o jcarith.o jcmainct.o pngtrans.o jcinit.o jcsample.o jquant1.o pngread.o jidctint.o jcapimin.o上記リストは、後でコマンドに引数として食わせるときに使いやすいようテキストファイルなどに書いておきます。
$ echo "jutils.o pngrio.o ..." > duplicate_lib_listOpenCVをアーキテクチャごとに分解する
lipoコマンドを使って、フレームワークフォルダ内のopencv2をアーキテクチャごとに分解します。
まず何が含まれているか以下コマンドで確認して、
$ cd opencv2.framework $ lipo -info opencv2 Architectures in the fat file: opencv2 are: armv7 armv7s i386 x86_64 arm64以下コマンドでバラします。
$ lipo -thin armv7 opencv2 -output opencv2_armv7 $ lipo -thin armv7s opencv2 -output opencv2_armv7s $ lipo -thin i386 opencv2 -output opencv2_i386 $ lipo -thin x86_64 opencv2 -output opencv2_x86_64 $ lipo -thin arm64 opencv2 -output opencv2_arm64競合が起きているファイルを削除する
バラしたファイルに対して以下コマンドを実行して、競合が起きているファイルをそれぞれから削除します。
$ cat duplicate_lib_list | xargs ar -dv opencv2_armv7 $ cat duplicate_lib_list | xargs ar -dv opencv2_armv7s $ cat duplicate_lib_list | xargs ar -dv opencv2_i386 $ cat duplicate_lib_list | xargs ar -dv opencv2_x86_64 $ cat duplicate_lib_list | xargs ar -dv opencv2_arm64バラしたファイルから再生成する
以下コマンドを実行してopencv2を再生成しましょう。
$ lipo -create opencv2_arm64 opencv2_armv7 opencv2_armv7s opencv2_i386 opencv2_x86_64 -output opencv2あとは途中作ったテキストファイルなどの余計なファイルを削除してリビルドしましょう。
競合が解消されてビルドできるようになっているはずです!参考記事
- 投稿日:2021-01-20T21:06:04+09:00
今更だけどUIViewの座標変換系メソッドを理解する(Swift)
はじめに
ごくまれに
UIView
の convert 系のメソッドを使って座標を変換したいときがありますがいつもどっちに何指定するのかな?と忘れるのでまとめておきます。View 準備
下記のような構成で座標変換をしてみます。
ScrollView を ViewController の View と同じサイズで配置してその中に
contentView
(緑色)を幅は ScrollView と同じ高さは 1200 pt で配置しています(StackView は左端のメモリ用です)。contentView
の中に縦横 120 pt のtargetView
(白色)をcontentView
の Top 900pt、横は中央寄せで配置して、そのtargetView
(白色)の中心にボタンを配置しています。座標変換
座標変換には
UIView
に下記のメソッドが用意されており、これを使って変換します。どちらのメソッドも対象の View は同一 Window にある必要があります。引数の
view
がnil
の場合は Window の座標系に変換されます。convert(_: to:)
point
はレシーバーの座標系を指定し、view
には変換したい座標系の View を指定します。func convert(_ point: CGPoint, to view: UIView?) -> CGPoint // ex. aView.convert(CGPoint.zero, to: bView)例だと
aView
の左上の座標をbView
の座標系に変換しています。convert(_: from:)
point
はview
の座標系を指定し、レシーバーの座標系に変換します。func convert(_ point: CGPoint, from view: UIView?) -> CGPoint // ex. aView.convert(CGPoint.zero, from: bView)例だと
bView
の左上の座標をaView
の座標系に変換しています。実践
ボタン押下時に
targetView
の座標系からscrollView
と ViewController のview
の座標系に変換してみます!@IBAction private func convertPoints(_ sender: Any) { // targetViewの右上の座標をscrollViewの座標系に変換 let p1 = targetView.convert(CGPoint.zero, to: scrollView) print("p1: \(p1)") // p1: (127.5, 900.0) // targetViewの右上の座標をviewの座標系に変換 let p2 = targetView.convert(CGPoint.zero, to: view) print("p2: \(p2)") // p2: (127.5, 367.0) * scrollViewのoffsetで変わる // targetViewの右上の座標をscrollViewの座標系に変換 let p3 = scrollView.convert(CGPoint.zero, from: targetView) print("p3: \(p3)") // p3: (127.5, 900.0) // targetViewの右上の座標をviewの座標系に変換 let p4 = view.convert(CGPoint.zero, from: targetView) print("p4: \(p4)") // p4: (127.5, 367.0) * scrollViewのoffsetで変わる }上記を見てもらうと分かる通り、p1 と p3、p2 と p4 は同じ結果になります。
これを使ってボタン押下時に
targetView
が画面外にある場合にスクロールのオフセットを調節してみます。@IBAction private func convertPoints(_ sender: Any) { // targetViewの左下の座標をviewの座標系に変換 let p1 = targetView.convert(CGPoint(x: 0, y: targetView.frame.height), to: view) // targetViewの左下がviewの範囲内か確認 if !view.frame.contains(p1) { // targetViewが画面内におさまるようスクロール let p2 = targetView.convert(CGPoint(x: 0, y: targetView.frame.height), to: scrollView) scrollView.setContentOffset(.init(x: 0, y: p2.y - scrollView.frame.height), animated: true) } }こんな感じです
おわりに
to と from の意味を考えたらわかるんですが
point
はどの座標系のやついれればいいんだっけ?とよく迷います。。。もうこれで迷わない!!(たぶん)
ちなみに Rect の変換メソッドもあります。
* convert(_: to:)
* convert(_: from:)SwiftUI になるとこういうの使うこともなくなるのかな
参考
- 投稿日:2021-01-20T19:37:30+09:00
Swift 繰り返し文まとめ
はじめに
この記事には、Swiftで多用する繰り返し文についてまとめました。
参考文献
この記事は以下の情報を参考にして執筆しました。
目次
- for-in文 - シーケンスの要素の列挙
- while文 - 継続条件による繰り返し
- repeat-while文 - 初回実行を保証する繰り返し
- 実行文の中断
1. for-in文 - シーケンスの要素の列挙
Sequenceプロトコルに準拠した型(ArrayやDittionary等)の要素にアクセスするための制御構文。
各要素を実行文に順次渡しながらその要素の数だけ繰り返す。
実行文内では、要素名として指定した名前の定数を通じて要素にアクセスできる。
for 要素名 in シーケンス {
要素ごとに繰り返し実行される文
}
Array型の要素をfor-in文で列挙する場合、要素の型はElement型となる。
Dictionary型の要素をfor-in文で列挙する場合、要素の型は(Key, Value)型のタプルとなる。2. while文 - 継続条件による繰り返し
条件式が成り立つ限り繰り返しを続ける制御構文。
while文は条件式と繰り返し実行される文から構成されている。
while文の条件式は、if文やfor-in文と同様にBool型を返す必要がある。
条件式は実行文の実行前に毎回評価され、結果がtrueであれば繰り返しを継続し、falseであれば繰り返しを停止し、while文全体の処理を終了する。
while 条件式 {
条件式が成立する間、繰り返し実行される文
}
3. repeat-while文 - 初回実行を保証する繰り返し
通常while文は実行前に評価を行うので、場合によっては一度も処理が行われない場合がある。だが、repeat-while文を使えば条件式は実行文の後に評価されるので条件の成否に関わらず、必ず一回は処理が行われる。
repeat {
一回は必ず処理され、それ以降は条件式が成立する限り繰り返し実行される文
} while 条件式
4. 実行文の中断
break文 - 繰り返しの終了
実行文を中断し、繰り返し文全体を終了する。
これ以上繰り返しを行う必要がない場合などに使用する。continue文 - 繰り返しの継続
実行文を中断した後、後続の繰り返しを継続する。
特定の場面だけ処理をスキップしたい場合など使用する。
continue文は、continueキーワードのみかラベルとの組み合わせで使用する。ラベル - break文やcontinue文の制御対象の指定
break文やcontinue文はラベルを用いて制御対象を指定できる。
ネストした繰り返しから一度退出する場合などに使用する。
ラベルによって繰り返し文を参照可能にするには、繰り返し文の前にラベル名:を追加する。
ラベル名: 繰り返し文
breakやcontinueキーワードに続けてラベル名を追加することで対象の繰り返し文を明示する。
break ラベル名
continue ラベル名
- 投稿日:2021-01-20T18:04:27+09:00
【Swift】スワイプ処理を実装する
はじめに
アプリ開発していく中で、スワイプジェスチャーを使用しました。そこで今回はスワイプジェスチャーについてまとめます。
開発環境
- macOS Catalina version10.15.7
- Xcode version12.2
- Swift5
様々なジェスチャー
Appleのヒューマンインターフェースガイドラインより、様々なジェスチャーの動画を確認できます。
Human Interface Guidelinesガイドラインを見ていて、フリックとスワイプって何が違うのか?と思ったので調べてみました。
フリックとスワイプの違いは?
フリック:画面を指で軽くはじくイメージ。文字入力などに使う。
スワイプ:画面に指を触れたままスライドさせるイメージ。画面遷移などに使う。参考サイト:「スワイプ」と「フリック」の違い・活用術 今さら聞けないスマホの基本操作
確かにフリック入力って言いますね。(自分は文字入力はタップ入力に慣れてしまっているためイメージしにくかったのかも)
スワイプ処理実装
全体のコード
import UIKit //UIGestureRecognizerDelegateを追加する class ViewController: UIViewController, UIGestureRecognizerDelegate { override func viewDidLoad() { super.viewDidLoad() //上スワイプ用のインスタンスを生成する let upSwipe = UISwipeGestureRecognizer( target: self, action: #selector(ViewController.didSwipe(_:)) ) upSwipe.direction = .up self.view.addGestureRecognizer(upSwipe) //右スワイプ用のインスタンスを生成する let rightSwipe = UISwipeGestureRecognizer( target: self, action: #selector(ViewController.didSwipe(_:)) ) rightSwipe.direction = .right self.view.addGestureRecognizer(rightSwipe) //下スワイプ用のインスタンスを生成する let downSwipe = UISwipeGestureRecognizer( target: self, action: #selector(ViewController.didSwipe(_:)) ) downSwipe.direction = .down self.view.addGestureRecognizer(downSwipe) //左スワイプ用のインスタンスを生成する let leftSwipe = UISwipeGestureRecognizer( target: self, action: #selector(ViewController.didSwipe(_:)) ) leftSwipe.direction = .left self.view.addGestureRecognizer(leftSwipe) } //スワイプ時に実行されるメソッド @objc func didSwipe(_ sender: UISwipeGestureRecognizer) { //スワイプ方向による実行処理をcase文で指定 switch sender.direction { case .up: //上スワイプ時に実行したい処理 case .right: //右スワイプ時に実行したい処理 case .down: //下スワイプ時に実行したい処理 case .left: //左スワイプ時に実行したい処理 default: break } } }参考:【Swift/UIKit】タップ・長押し・スワイプを認識させる
解説
スワイプ処理は、方向の指定箇所以外は同じ処理のためここでは上スワイプ処理のコードを使って簡単に説明します。
//上スワイプ用のインスタンスを生成する let upSwipe = UISwipeGestureRecognizer( target: self, action: #selector(ViewController.didSwipe(_:)) ) upSwipe.direction = .up self.view.addGestureRecognizer(upSwipe)タップ、ロングプレスと同様に、まずはインスタンスを生成する。
その際に、スワイプジェスチャー時に実行したいメソッドを指定する。
メソッド指定時に#selector
を使用している理由や、メソッド定義時に@objc
は下記の通りです。target-actionはObjective-Cで実装された仕組みで、target-actionで指定するのはObjective-Cのメソッドである必要がある。そのため、メソッド定義時は@objcをつけている。
また、Swiftでは#selectorによってObjective-Cのメソッドを指定できるとのこと。
参考:【Swift】タップ、ロングプレス処理を実装する!
upSwipe.direction = .updirectionよりスワイプの方向を指定する。
スワイプの方向は全部で4つ。right
,left
,up
,down
公式ドキュメント UISwipe Gesture Recognizer .Direction
self.view.addGestureRecognizer(upSwipe)
addGestureRecognizer()
でスワイプイベントをviewに追加しています。
//スワイプ時に実行されるメソッド @objc func didSwipe(_ sender: UISwipeGestureRecognizer) { //スワイプ方向による実行処理をcase文で指定 switch sender.direction { case .up: //上スワイプ時に実行したい処理 case .right: //右スワイプ時に実行したい処理 case .down: //下スワイプ時に実行したい処理 case .left: //左スワイプ時に実行したい処理 default: break } }各スワイプ時に実行する処理がこちらになります。
Switch文を用いて、スワイプの方向によって実行する処理を設定しています。【おまけ】ジェスチャーを無効、有効化するには?
最初ジェスチャーの無効、有効化を調べていたところ下記コードでできるという記事を見つけました。
UIApplication.shared.beginIgnoringInteractionEvents() //無効化 UIApplication.shared.endIgnoringInteractionEvents() //有効化しかし、実装してみたところ下記警告が出ました。
beginIgnoringInteractionEvents()' was deprecated in iOS 13.0: Use UIView's userInteractionEnabled property instead
どうやら、iOS13より上記コードは非推奨になったらしいです。
userInteractionEnabled
を使ってくださいとのことでした。
userInteractionEnabled
を用いた無効、有効化はこちらになります。self.view.isUserInteractionEnabled = false //ジェスチャー無効 self.view.isUserInteractionEnabled = true //ジェスチャー有効(デフォルト値)参考:公式ドキュメント isUserInteractionEnabled
まとめ
今回はスワイプ処理に関する学んだことをまとめました。
普段何気なく使っているスワイプ処理がこんな感じで実装されているんだなぁと知ることができて勉強になりました。以上。
- 投稿日:2021-01-20T17:37:58+09:00
【Swift5】iOSの設定アプリに遷移するための処理と注意点
iOSの設定アプリに遷移させるための処理
guard let url = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(url) else { return } UIApplication.shared.open(url, options: [:], completionHandler: nil)注意点
①設定アプリに遷移するときの挙動
「設定アプリ」内にアプリ固有の設定項目がある場合は、アプリ固有の設定画面へ遷移します。
詳細な挙動については、下記の記事が参考になります。
UIApplicationOpenSettingsURLStringから設定アプリを開いたときの挙動調査
②設定アプリの特定の画面に遷移させる処理(
App-Prefs:root=
)を使うとリジェクトされる設定アプリの特定の画面に遷移させるとリジェクトされた例があるらしいので注意が必要です。
詳しくは下記記事に書かれています。
App-Prefs:root= を使っていたため2.5.1リジェクトされたときの対処法
- 投稿日:2021-01-20T13:19:37+09:00
gem install cocoapods に 失敗('ruby/config.h' file not found)
少しハマったので備忘録として残しておきます。
環境
MacOS : Big Sur 11.1 (20C69)
Xcode : Version 12.3 (12C33)経緯
pod コマンドを使用したところ、cocoapodsをアップデートしてねと言われる
% pod outdated Ignoring ffi-1.13.1 because its extensions are not built. Try: gem pristine ffi --version 1.13.1 Ignoring iStats-1.6.1 because its extensions are not built. Try: gem pristine iStats --version 1.6.1 Updating spec repo `trunk` CocoaPods 1.10.1 is available. To update use: `sudo gem install cocoapods` :エラー内容
ほいほいとアップデート実行すると以下のエラーが発生
% sudo gem install cocoapods Password: Ignoring ffi-1.13.1 because its extensions are not built. Try: gem pristine ffi --version 1.13.1 Ignoring iStats-1.6.1 because its extensions are not built. Try: gem pristine iStats --version 1.6.1 ERROR: Error installing cocoapods: ERROR: Failed to build gem native extension. current directory: /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/ext/ffi_c /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210120-82832-1x09kaf.rb extconf.rb checking for ffi.h... /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError) You have to install development tools first. from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1109:in `block in have_header' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1108:in `have_header' from extconf.rb:10:in `system_libffi_usable?' from extconf.rb:42:in `<main>' To see why this extension failed to compile, please check the mkmf.log which can be found here: /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/ffi-1.13.1/mkmf.log extconf failed, exit code 1 Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1 for inspection. Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/ffi-1.13.1/gem_make.out
/Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/ffi-1.13.1/mkmf.log
上記のエラーログを見てねと言われる。/Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/ffi-1.13.1/mkmf.logpackage configuration for libffi is not found "xcrun clang -o conftest -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/universal-darwin20 -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby/backward -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -g -Os -pipe -DHAVE_GCC_ATOMIC_BUILTINS -DUSE_FFI_CLOSURE_ALLOC conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib -L. -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.Internal.sdk/usr/local/lib -lruby.2.6 " In file included from conftest.c:1: In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby.h:33: /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby/ruby.h:24:10: fatal error: 'ruby/config.h' file not found #include "ruby/config.h" ^~~~~~~~~~~~~~~ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby/ruby.h:24:10: note: did not find header 'config.h' in framework 'ruby' (loaded from '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks') 1 error generated. checked program was: /* begin */ 1: #include "ruby.h" 2: 3: int main(int argc, char **argv) 4: { 5: return 0; 6: } /* end */対処方法
Xcode の設定(Preferences)から「Locations」タブを開く
「Command Line Tools」が空だったので 「Xcode 12.3(12C33)」を選択上記の設定を行い、再度
sudo gem install cocoapods
を実行したところ無事インストール完了しました。参考
https://stackoverflow.com/questions/26434642/yosemite-upgrade-broke-ruby-h
- 投稿日:2021-01-20T05:55:47+09:00