20220117のiOSに関する記事は4件です。

ARでメタバース 巨大ロボットを出現させる

大迫力の3Dオブジェクトを操作する方法 コンピュータのパワーでよりパワフルなコンテンツを ARってなんだか難しそうな印象ありますか? ARKitを使ってスマホでかんたん表示 実はかんたんだったりします。 AppleがARをかんたんに扱えるフレームワークを出してくれています。 手順 アップルのサイトからUSDZモデルを手に入れます。 https://developer.apple.com/jp/augmented-reality/quick-look/ ロボットという名前のUSDZファイルを読み込んでシーンに追加します。 guard let robot = try? Entity.load(named: "robot") else { return } let anchor = AnchorEntity(plane: .horizontal) // 平面に配置する anchor.addChild(robot) arView.scene.addAnchor(anchor) ロボットを100倍のスケールに大きくします。 robot.setScale([100,100,100], relativeTo: robot) ロボットを動かします。 for animation in robot.availableAnimations { robot.playAnimation(animation.repeat()) // 歩行アニメーション } robot.move(to: Transform(translation: [0,0,20]), relativeTo: robot, duration: 4, timingFunction: .easeInOut) // 実際に移動させる 詳しいサンプルコードはこちら ゲームや、映像、舞台インタラクションなど様々なコンテンツに ARコンテンツを表示するのは意外とかんたんです。色々な表現の可能性を探りたいですね。 ? フリーランスエンジニアです。 お仕事のご相談こちらまで rockyshikoku@gmail.com Core MLやARKitを使ったアプリを作っています。 機械学習/AR関連の情報を発信しています。 Twitter Medium
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

"rvictl"が"FAILED"になったときの解決策

はじめに 「rvictl」はiPhone(実機)の通信ログ(パケットのキャプチャ)を取得する際に使用されるコマンドです。 iPhoneをMacにライトニングケーブルに繋いだ後、Macから以下のコマンドを実行することで仮想的なネットワークカードが作成され、WiresharkなどからiPhoneの通信を参照することが可能となります。 $ rvictl -s "iPhoneのUDID" iPhone(実機)から通信ログ(パケットのキャプチャ)を参照する方法については、他の記事を参照すると良いでしょう。 参考記事 - iPhone(実機)の通信ログ(パケットのキャプチャ)を簡単に取得する方法 - MAC OS CatalinaでiPhoneの通信をキャプチャする方法 "rvictl"が"FAILED"になった # rvictl -s "iPhoneのUDID" あるとき、上記のコマンドを実行した場合、以下のように"FAILED"になってしまいました。 Starting device "iPhoneのUDID" [FAILED] こちらの解決策について書きたいと思います。 ちなみに、私の環境は以下の通りです。 項目 詳細 Mac Apple Silicon Macではない OS macOS Monterey バージョン 12.1 Xcode Version 13.2.1(13c100) iPhone iPhone11(iOS 15.2) 一応の確認 今回紹介するのは、あくまで以下のような"FAILED"になったときの解決策となります。 Starting device "iPhoneのUDID" [FAILED] もし、コマンドを実行しても何も起こらずにプロンプトが返ってくるのであれば、「UDIDが誤っている」可能性が高いかと思います。 その場合は、UDIDが大文字英数であれば小文字英数に変換したり、その逆を行なっていただければうまく行くかもしれません。 解決策 "rvictl"が"FAILED"になるのは、MacのOSがアップデートにより、Appleシステムのセキュリティパフォーマンスが改善されたためとのことです。(詳細は私も良くわかっていません。。) 以下を行うことで解決することができました。 Macをシャットダウンし、macOS 復旧システムで再起動させる。(macOS 復旧システムは、Mac起動時に「command(⌘) + R」を押下することでなることができます) macOS 復旧システムで起動したら、画面右上のメニューバーから「ターミナル」を起動 ターミナルから、コマンド「csrutil disable」を実行 Macをシャットダウンし、通常モードで再起動 通常モードで起動したら、「システム環境設定」 > 「セキュリティとプライバシー」へと遷移すると、「一般」タブの下部に「Apple.Incからの設定変更があります」(うろ覚え)のような文言が表示されますので、それを許可します。 これでOKです。再度「rvictl -s "iPhoneのUDID"」を実行しましょう。 おわりに macOS 復旧システムで実行したコマンド「csrutil disable」は、System Integrity Protection (SIP) を無効にするコマンドのようです。 iPhoneの通信ログを参照し終わったら、再度有効にした方が良いと思います。その場合は、上記の「3.」のコマンドを以下に置き換えれば、SIPを再び有効にすることができます。 # csrutil enable 以上、お役に立てたら幸いです。 参考 【上級者向け】System Integrity Protection (SIP) を無効にする方法 rvictl not working on big sur and ios 14 beta 3
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Mac]Flutterで保存したドキュメントのpath

iPhone sample.dart void _saveFile() async { final documents = await getApplicationDocumentsDirectory(); new Directory('${documents.path}/log').create().then((Directory directory) { print(directory.path);//ここでpath取得 final file = File('${directory.path}/test.log'); file.writeAsString('test'); }); } 普通に保存したパスをコンソール出力して FInde上でcmd + shft + Gにて貼り付ければ飛べます Android Androidの場合、上述のIPhoneの方法では出来ません [View] > [Tool Windows] > [Device File Explorer] data/data/アプリ名/app_flutter/以下にありました。 Finderのパスですと /Users/ユーザー名/Documents/AndroidStudio/DeviceExplorer/エミュレーター名/data/data/アプリ名/app_flutter/以下でした 人によって違うかもしれないので参考程度に 公式ドキュメント
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[iOS]SwiftでLocalizable.stringsを動的に差し替える

Swift で Localizable.strings を動的に差し替える 特に多言語対応しているiOSアプリでは、Localizable.strings を使ってアプリ内の文字列を管理している場合が多いと思います 私が作っているアプリでは、SwiftPM で作ったリソース用のモジュールがあり、Bundle.module.localizedString を使ってバンドルした文字列を取り出しています この方法では、翻訳データを更新するためには、アプリを再度ビルドする必要があります そこで、動的に Localizable.strings を差し替える仕組みを作ってみました うまくいったやり方 実際に作成したコードはこちらです 文字列データは、DynamicLocalize.localizedString を使って取り出します public class DynamicLocalize { internal static func localizedString(_ key: String, _ table: String) -> String { return bundle.localizedString(forKey: key, value: nil, table: table + ".nocache") } private static let bundleName = "DynamicLocalize.bundle" private static let bundleURL: URL = { let doc = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) return doc.first! .appendingPathComponent(bundleName, isDirectory: true) }() private static let bundle: Bundle = { let dir = bundleURL.appendingPathComponent("en.lproj") if !FileManager.default.fileExists(atPath: dir.path) { try! FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true, attributes: nil) } let url = dir.appendingPathComponent("Localizable.nocache.strings") try! "\"Key001\" = \"First Value\";".write(to: url, atomically: true, encoding: .utf8) return Bundle(url: bundleURL)! }() public static func update() { let url = bundleURL .appendingPathComponent("en.lproj") .appendingPathComponent("Localizable.nocache.strings") try! "\"Key001\" = \"\(UUID().uuidString)\";".write(to: url, atomically: true, encoding: .utf8) } } 実装上のポイント ドキュメントディレクトリ下に bundle のディレクトリを作成する Bundle.module は編集する事ができません そこで、ドキュメントディレクトリ下に作る必要があります 文字列のファイル名に、.nocache をつける これで、キャッシュされなくなります https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html Table 2-1 あたり 文字列を差し替えた時に、.nocache を付けておくことで、最新のデータが取得されます SwiftGen で DynamicLocalize を利用する 文字列を使う場所で毎回、localizedString すると大変なので、SwiftGen を利用して文字列データを管理したいです 設定ファイル(swiftgen.yml) はこちらです strings: inputs: - Modules/Sources/Assets/ResourceFiles/Locales/en.lproj filter: .+\.strings$ outputs: - templateName: structured-swift5 output: Modules/Sources/Assets/Generated/Strings+Generated.swift params: publicAccess: true enumName: AppLocales lookupFunction: DynamicLocalize.localizedString 実際に生成されるコードがこちらです public enum AppLocales { /// Value001 public static var key001: String { return AppLocales.tr("Localizable", "Key001") } } extension AppLocales { private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { let format = DynamicLocalize.localizedString(key, table) return String(format: format, locale: Locale.current, arguments: args) } } lookupFunction を指定したので、tr 内で、DynamicLocalize.localizedString が呼ばれています また、AppLocales.key001 が Stored property から Computed property に変わります おかげで stencil をいじらなくて済みました これで、AppLocales.key001 が呼ばれる度に、DynamicLocalize に問い合わせられるようになります 動的に差し替えられる文字列データを利用する AppLocales.key001 を利用できます DynamicLocalize.update() してから objectWillChange などで画面を再描画させると、文字列が更新されていることを確認できます import SwiftUI import Assets public struct ContentView: View { @ObservedObject var viewModel = ContentViewModel() public init() { } public var body: some View { VStack { Text(AppLocales.key001) Button("Update") { DynamicLocalize.update() viewModel.update() } } } } class ContentViewModel: ObservableObject { func update() { self.objectWillChange.send() } } まとめ 最終的にかなりシンプルな仕組みになりましたが、.nocache など辿り着くまで大変でした あと、SwiftGen は神
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む