RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/開発ツール
開発ツール/2026-03-30上級

Rork Max × ARKit × Core ML 統合開発ガイド — AI と拡張現実で次世代アプリを作る

Rork MaxのネイティブSwift機能を活用し、ARKitと Core MLを統合した高度な拡張現実アプリの開発方法を完全解説。リアルタイム物体認識から3Dオブジェクト配置、App Store審査対策までの実践テクニック。

Rork Max229ARKit2Core ML6拡張現実機械学習3SwiftUI63LiDAR23D

取り組みの背景:次世代アプリの実現ぞうけん

Apple のエコシステムは、拡張現実(AR)と AI の融合に最適化されています。ARKit 6 以降のシーン理解、LiDAR スキャナー、そして Core ML による高速推論を組み合わせることで、ユーザーの物理世界と デジタル コンテンツが自然に融合するアプリが実現できます。

Rork Max は Xcode IDE の全機能と Swift、SwiftUI への完全なアクセスを提供するため、ネイティブ Apple API を直接活用した高度な AR×AI 統合開発が可能です。ここでシーン理解から 3D オブジェクト配置、リアルタイム物体認識、そして App Store での承認まで、実務レベルの技術を段階的に解説します。

第1章:Rork Max のネイティブ Swift 機能概要

フルアクセス可能な Apple フレームワーク

Rork Max は以下の Core Framework にネイティブで対応しています:

AR/3D 関連:

  • ARKit(フルバージョン対応)
  • RealityKit
  • SceneKit
  • Metal

機械学習関連:

  • Core ML
  • Vision フレームワーク
  • Natural Language Processing

デバイス機能:

  • LiDAR センサーアクセス
  • IMU(加速度計・ジャイロ)
  • Camera API(最大 24-bit Color)

パフォーマンス:

  • Metal GPU アクセス
  • スレッド管理
  • メモリ最適化

なぜ Rork Max なのか?

従来の Web ベース AR フレームワーク(Three.js + WebGL)に比べて、Rork Max は以下の優位性があります:

  1. フレームレート: 60fps 以上を安定維持(Web は 30fps)
  2. LiDAR アクセス: iPhone 12 Pro 以降の LiDAR を直接制御
  3. 推論速度: Core ML は GPU 推論で 10〜50ms 処理(Web ML.js は 100〜500ms)
  4. バッテリー効率: Metal + ARKit の最適化により 3 倍以上の省電力化

第2章:ARKit の基礎と Rork Max での実装

シーン理解(Scene Understanding)

ARKit 6 のシーン理解機能は、リアルタイムで物理空間を 3D メッシュに変換します。

// ARKit フレーム更新時のシーン理解処理
import ARKit
import RealityKit
 
let arView = ARView(frame: .zero)
let configuration = ARWorldTrackingConfiguration()
 
// シーン理解の有効化
if ARWorldTrackingConfiguration.supportsFrameSemantics(.personSegmentationWithDepth) {
    configuration.frameSemantics.insert(.personSegmentationWithDepth)
}
 
if ARWorldTrackingConfiguration.supportsFrameSemantics(.sceneMesh) {
    configuration.frameSemantics.insert(.sceneMesh)
}
 
arView.session.run(configuration)

シーン理解の主要な利点:

  • 自動平面検出: 床・机・壁を自動認識
  • 深度マップ: 各ピクセルの距離情報を取得
  • セマンティックセグメンテーション: 人物・家具・背景を分類

LiDAR スキャン統合

LiDAR センサーを使用することで、毎フレーム数百万ポイントの 3D 座標を取得できます。

// LiDAR からの深度データ取得
import ARKit
 
extension ARFrame {
    func getLidarDepthMap() -> CVPixelBuffer? {
        if let depthMap = self.segmentationBuffers?.depthBuffer {
            return depthMap
        }
        return nil
    }
}
 
// 深度マップから 3D ポイントクラウド生成
func generatePointCloud(from depthFrame: ARFrame) -> [SIMD3<Float>] {
    var points: [SIMD3<Float>] = []
 
    if let depthBuffer = depthFrame.segmentationBuffers?.depthBuffer {
        let width = CVPixelBufferGetWidth(depthBuffer)
        let height = CVPixelBufferGetHeight(depthBuffer)
 
        CVPixelBufferLockBaseAddress(depthBuffer, .readOnly)
        defer { CVPixelBufferUnlockBaseAddress(depthBuffer, .readOnly) }
 
        let baseAddress = CVPixelBufferGetBaseAddress(depthBuffer)
        let bytesPerRow = CVPixelBufferGetBytesPerRow(depthBuffer)
 
        let floatBuffer = unsafeBitCast(baseAddress, to: UnsafeMutablePointer<Float>.self)
 
        for y in stride(by: 2, to: height, by: 2) {
            for x in stride(by: 2, to: width, by: 2) {
                let depth = floatBuffer[y * bytesPerRow / 4 + x]
 
                if depth > 0 && depth < 8.0 {
                    let pointX = (Float(x) - Float(width) / 2) * depth
                    let pointY = (Float(y) - Float(height) / 2) * depth
                    let pointZ = depth
 
                    points.append(SIMD3(pointX, pointY, pointZ))
                }
            }
        }
    }
 
    return points
}

3D オブジェクト配置と操作

ARKit のアンカー(Anchor)を使用して、仮想オブジェクトを現実空間に配置します。

// ModelEntity を使用した 3D オブジェクト配置
import RealityKit
 
func placeObject(in arView: ARView, at anchor: AnchorEntity) -> ModelEntity? {
    // USDZ モデルロード(App Bundle から)
    guard let model = try? ModelEntity.loadModel(named: "furniture") else {
        return nil
    }
 
    model.move(to: Transform(translation: [0, 0, -0.5]))
    anchor.addChild(model)
 
    // インタラクション:ジェスチャーで回転・スケール変更
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
    arView.addGestureRecognizer(tapGesture)
 
    return model
}
 
@objc func handleTap(_ gesture: UITapGestureRecognizer) {
    let location = gesture.location(in: arView)
 
    if let result = arView.raycast(from: location, allowing: .estimatedPlane, alignment: .horizontal).first {
        var transform = result.worldTransform
        transform.translation.y += 0.1
 
        let anchor = AnchorEntity(plane: .horizontal)
        anchor.setTransformMatrix(transform, relativeTo: anchor.parent)
 
        arView.scene.addAnchor(anchor)
    }
}

ワールドトラッキングとアンカー管理

複数の AR オブジェクトを配置するとき、デバイス移動に対応させるには堅牢なアンカー管理が必須です。

// マルチオブジェクト配置とアンカー追跡
class ARObjectManager {
    var anchors: [String: AnchorEntity] = [:]
    let arView: ARView
 
    init(arView: ARView) {
        self.arView = arView
    }
 
    func addObject(id: String, model: ModelEntity, at position: SIMD3<Float>) {
        let anchor = AnchorEntity(world: [position.x, position.y, position.z])
        anchor.addChild(model)
 
        arView.scene.addAnchor(anchor)
        anchors[id] = anchor
    }
 
    func updatePosition(id: String, newPosition: SIMD3<Float>) {
        if let anchor = anchors[id] {
            anchor.move(to: Transform(translation: newPosition))
        }
    }
 
    func removeObject(id: String) {
        if let anchor = anchors[id] {
            arView.scene.removeAnchor(anchor)
            anchors.removeValue(forKey: id)
        }
    }
}

第3章:Core ML との統合

事前学習済みモデルのデプロイ

Core ML は、TensorFlow、PyTorch、scikit-learn などで学習したモデルを .mlmodel フォーマットに変換してデプロイします。

// 画像分類モデルの読み込みと実行
import CoreML
import Vision
 
class ImageClassifier {
    let model: MLModel
 
    init(modelName: String) throws {
        guard let modelURL = Bundle.main.url(forResource: modelName, withExtension: "mlmodelc") else {
            throw NSError(domain: "Model not found", code: 1)
        }
        self.model = try MLModel(contentsOf: modelURL)
    }
 
    func classify(image: UIImage) -> [(label: String, confidence: Double)]? {
        guard let pixelBuffer = image.toCVPixelBuffer() else { return nil }
 
        do {
            let input = MLFeatureProvider(dictionary: ["image": MLFeatureValue(pixelBuffer: pixelBuffer)])
            let output = try model.prediction(from: input)
 
            // 出力をパース
            var results: [(String, Double)] = []
 
            if let featureDict = output.featureValue(for: "classLabel")?.dictionaryValue as? [String: NSNumber] {
                for (label, probability) in featureDict {
                    if let prob = probability as? Double {
                        results.append((label, prob))
                    }
                }
            }
 
            return results.sorted { $0.confidence > $1.confidence }
        } catch {
            print("分類エラー: \(error.localizedDescription)")
            return nil
        }
    }
}
 
extension UIImage {
    func toCVPixelBuffer() -> CVPixelBuffer? {
        let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue,
                     kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
 
        var pixelBuffer: CVPixelBuffer?
        let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(size.width), Int(size.height),
                                        kCVPixelFormatType_32ARGB, attrs, &pixelBuffer)
 
        guard status == kCVReturnSuccess, let pixelBuffer = pixelBuffer else {
            return nil
        }
 
        CVPixelBufferLockBaseAddress(pixelBuffer, .readAndWrite)
        defer { CVPixelBufferUnlockBaseAddress(pixelBuffer, .readAndWrite) }
 
        let context = CGContext(data: CVPixelBufferGetBaseAddress(pixelBuffer),
                               width: Int(size.width), height: Int(size.height),
                               bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer),
                               space: CGColorSpaceCreateDeviceRGB(),
                               bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue)
 
        context?.draw(cgImage!, in: CGRect(origin: .zero, size: size))
 
        return pixelBuffer
    }
}

オンデバイス推論の利点と制約

利点:

  • ネットワーク遅延なし(< 50ms)
  • プライバシー:データはデバイス内に保存
  • バッテリー効率:GPU 推論で省電力

制約:

  • モデルサイズ: App Bundle に含まれるため、通常 500MB 未満に制限
  • 精度:量子化により若干の精度低下(通常 1〜3%)
  • リアルタイム性:複雑なモデルは フレームスキップが発生

物体検出モデル(YOLO)の統合

YOLO(You Only Look Once)は、単一の CNN パスで複数の物体を検出できる高速モデルです。

// YOLO 物体検出モデルの実装
import CoreML
import Vision
 
class YOLODetector {
    let model: VNCoreMLModel
 
    init(modelName: String) throws {
        let mlModel = try MLModel(contentsOf: Bundle.main.url(forResource: modelName,
                                                             withExtension: "mlmodelc")!)
        self.model = try VNCoreMLModel(for: mlModel)
    }
 
    func detectObjects(in image: UIImage, completion: @escaping ([(label: String, bbox: CGRect, confidence: Float)]) -> Void) {
        guard let cgImage = image.cgImage else { return }
 
        let request = VNCoreMLRequest(model: model) { request, error in
            guard let results = request.results as? [VNRecognizedObjectObservation] else {
                completion([])
                return
            }
 
            let detections = results.map { observation -> (String, CGRect, Float) in
                let label = observation.labels.first?.identifier ?? "Unknown"
                let confidence = observation.labels.first?.confidence ?? 0
                let bbox = VNImageRectForNormalizedRect(observation.boundingBox, Int(image.size.width), Int(image.size.height))
 
                return (label, bbox, confidence)
            }
 
            completion(detections)
        }
 
        let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
        try? handler.perform([request])
    }
}

第4章:ARKit + Core ML の統合

リアルタイム物体認識 AR

カメラフレームを 毎フレーム 分析し、認識した物体の上に 3D ラベルを表示します。

// リアルタイム物体認識を伴う AR ビュー
class ObjectRecognitionARViewController: UIViewController, ARViewDelegate {
    @IBOutlet var arView: ARView!
    let detector = YOLODetector(modelName: "YOLOv8n")
    var recognitionAnchors: [String: AnchorEntity] = [:]
 
    override func viewDidLoad() {
        super.viewDidLoad()
        setupAR()
        startObjectDetection()
    }
 
    func setupAR() {
        let configuration = ARWorldTrackingConfiguration()
        configuration.planeDetection = [.horizontal, .vertical]
 
        if ARWorldTrackingConfiguration.supportsFrameSemantics(.sceneMesh) {
            configuration.frameSemantics.insert(.sceneMesh)
        }
 
        arView.session.run(configuration)
    }
 
    func startObjectDetection() {
        Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] _ in
            guard let self = self,
                  let frame = self.arView.session.currentFrame else { return }
 
            let image = UIImage(ciImage: CIImage(cvPixelBuffer: frame.capturedImage))
 
            self.detector.detectObjects(in: image) { [weak self] detections in
                DispatchQueue.main.async {
                    self?.updateDetectionLabels(detections, for: frame)
                }
            }
        }
    }
 
    func updateDetectionLabels(_ detections: [(String, CGRect, Float)], for frame: ARFrame) {
        // 既存アンカーをクリア
        recognitionAnchors.forEach { arView.scene.removeAnchor($0.value) }
        recognitionAnchors.removeAll()
 
        for (label, bbox, confidence) in detections.filter({ $0.2 > 0.6 }) {
            // バウンディングボックスの中心を 3D ワールド座標に変換
            let screenPoint = CGPoint(x: bbox.midX, y: bbox.midY)
 
            if let result = arView.raycast(from: screenPoint, allowing: .estimatedPlane, alignment: .horizontal).first {
                let anchor = AnchorEntity(world: result.worldTransform.translation)
 
                // テキストモデルを作成(3D Text)
                let modelEntity = createTextModel(label: label, confidence: confidence)
                anchor.addChild(modelEntity)
 
                arView.scene.addAnchor(anchor)
                recognitionAnchors[label + UUID().uuidString] = anchor
            }
        }
    }
 
    func createTextModel(label: String, confidence: Float) -> ModelEntity {
        // 簡易実装:3D キューブに テキストを描画
        var material = Material()
        material.color = .init(tint: .systemBlue, texture: nil)
 
        let mesh = MeshResource.generateBox(size: [0.1, 0.1, 0.1])
        let model = ModelEntity(mesh: mesh, materials: [material])
 
        return model
    }
}

AR 内部設計UI:店舗シミュレーション

家具配置 AR アプリの実装例:

// 家具配置 AR シミュレーション
class FurnitureARView: UIViewController {
    @IBOutlet var arView: ARView!
    var selectedFurniture: String = "chair"
    var placedObjects: [ModelEntity] = []
 
    override func viewDidLoad() {
        super.viewDidLoad()
        setupAR()
        setupGestures()
    }
 
    func setupGestures() {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handlePlacement(_:)))
        arView.addGestureRecognizer(tapGesture)
 
        let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleRotation(_:)))
        arView.addGestureRecognizer(longPressGesture)
    }
 
    @objc func handlePlacement(_ gesture: UITapGestureRecognizer) {
        let location = gesture.location(in: arView)
 
        guard let result = arView.raycast(from: location, allowing: .estimatedPlane, alignment: .horizontal).first else {
            return
        }
 
        // 家具モデルをロード・配置
        if let furniture = try? ModelEntity.loadModel(named: selectedFurniture) {
            let anchor = AnchorEntity(world: result.worldTransform.translation)
            anchor.addChild(furniture)
 
            arView.scene.addAnchor(anchor)
            placedObjects.append(furniture)
        }
    }
 
    @objc func handleRotation(_ gesture: UILongPressGestureRecognizer) {
        let location = gesture.location(in: arView)
 
        guard let hitObject = arView.entity(at: location) as? ModelEntity else { return }
 
        switch gesture.state {
        case .changed:
            var transform = hitObject.transform
            transform.translation.y += 0.01
            hitObject.move(to: transform)
        default:
            break
        }
    }
}

教育用 AR 体験:リアルタイム解説

生物学教育の AR アプリ:細胞の構造を 3D で表示・説明

// 教育用 AR:細胞構造の 3D 可視化
class CellARViewController: UIViewController {
    @IBOutlet var arView: ARView!
 
    struct CellComponent {
        let name: String
        let model: ModelEntity
        let description: String
    }
 
    var cellComponents: [CellComponent] = []
 
    func displayCell(_ cellType: String) {
        let anchor = AnchorEntity(plane: .horizontal)
 
        // 各細胞小器官を配置
        let organelles = [
            (name: "核", offset: [0, 0.2, 0]),
            (name: "ミトコンドリア", offset: [-0.15, 0, 0]),
            (name: "小胞体", offset: [0.15, 0, 0]),
            (name: "ゴルジ体", offset: [0, -0.15, 0])
        ]
 
        for organelle in organelles {
            if let model = try? ModelEntity.loadModel(named: organelle.name) {
                model.move(to: Transform(translation: SIMD3(organelle.offset[0], organelle.offset[1], organelle.offset[2])))
                anchor.addChild(model)
            }
        }
 
        arView.scene.addAnchor(anchor)
    }
}

第5章:高度な プロンプトエンジニアリング

Rork Max でネイティブ機能の複雑な実装を指示するとき、プロンプトの精度が重要です。

効果的な指示パターン

パターン 1:メモリ管理の明示

"ARFrame のピクセルバッファから効率的に深度データを抽出する Swift
コードを書いてください。以下を満たしてください:
- CVPixelBufferLockBaseAddress/UnlockBaseAddress を正しく使う
- メモリリークが発生しない
- フレームレート低下を避けるため処理は 16ms 以内"

パターン 2:GPU 最適化の指示

"Core ML の推論結果をリアルタイムで AR シーンに反映するとき、
GPU 推論とメインスレッド同期の衝突を回避する設計を示してください。
GCD(DispatchQueue)の使い分けを含める"

パターン 3:権限リクエストの組み込み

"カメラ+マイク+位置情報へのアクセス権をリクエストする初期化フローを
実装してください。Info.plist への記載も含める"

Rork Max での複雑なプロンプト例

Rork Max を使用して以下の機能を実装してください:
1. ARWorldTrackingConfiguration でシーン理解・LiDAR・深度を有効化
2. フレーム更新ごとに Vision フレームワークで YOLO 物体検出
3. 検出結果を ARAnchors にマッピング
4. 各オブジェクトに 3D テキストラベルを表示
5. タップでラベルを削除可能に
6. パフォーマンス:毎フレーム 16ms 以内の処理時間

第6章:パフォーマンス最適化

Metal による GPU 統合

高負荷な計算を CPU ではなく GPU に オフロードします。

// Metal を使用した 深度マップの処理
import Metal
 
class MetalDepthProcessor {
    let device: MTLDevice
    let commandQueue: MTLCommandQueue
    let computePipeline: MTLComputePipelineState
 
    init?() {
        guard let device = MTLCreateSystemDefaultDevice(),
              let queue = device.makeCommandQueue() else {
            return nil
        }
 
        self.device = device
        self.commandQueue = queue
 
        let library = device.makeDefaultLibrary()
        let function = library?.makeFunction(name: "depthFilter")
 
        self.computePipeline = try? device.makeComputePipelineState(function: function!)
    }
 
    func processDepth(_ depthBuffer: CVPixelBuffer) {
        let width = CVPixelBufferGetWidth(depthBuffer)
        let height = CVPixelBufferGetHeight(depthBuffer)
 
        guard let commandBuffer = commandQueue.makeCommandBuffer(),
              let computeEncoder = commandBuffer.makeComputeCommandEncoder() else {
            return
        }
 
        computeEncoder.setComputePipelineState(computePipeline)
        computeEncoder.dispatchThreads(MTLSizeMake(width, height, 1),
                                      threadsPerThreadgroup: MTLSizeMake(8, 8, 1))
        computeEncoder.endEncoding()
 
        commandBuffer.commit()
        commandBuffer.waitUntilCompleted()
    }
}

フレームレート管理

60fps を維持するため、以下の最適化を実施します:

// フレームレート制御と優先度調整
class ARPerformanceManager {
    var lastFrameTime: CFTimeInterval = 0
    let targetFrameTime: CFTimeInterval = 1.0 / 60.0
 
    func manageFrameRate(in session: ARSession) {
        let now = CACurrentMediaTime()
 
        if now - lastFrameTime < targetFrameTime {
            // フレームをスキップして次の処理へ
            return
        }
 
        lastFrameTime = now
 
        // 重い処理は非同期に
        DispatchQueue.global(qos: .userInitiated).async {
            // Core ML 推論など
        }
    }
}

第7章:AR アプリのテスト戦略

シミュレータでの限定テスト

ARKit はシミュレータで限定的にサポートされます。

// シミュレータ対応コード
#if targetEnvironment(simulator)
// シミュレータ:Mock ARFrame
func createMockARFrame() -> ARFrame {
    // テスト用のダミーフレームを生成
    let mockTransform = simd_float4x4(columns: (
        SIMD4(1, 0, 0, 0),
        SIMD4(0, 1, 0, 0),
        SIMD4(0, 0, 1, 0),
        SIMD4(0, 0, -1, 1)
    ))
    // 実装...
}
#else
// 実機:本物の ARFrame を使用
#endif

実機でのテスト手順

  1. iPhone 12 Pro 以降で LiDAR を確認
  2. App Store Connect TestFlight で配布
  3. ベータテスターから ユーザー体験フィードバックを収集
  4. クラッシュレポート(Crashes)を監視

第8章:App Store ガイドラインと審査対策

AR アプリの必須要件

フレームワーク要件:

  • ARKit 6 以上を使用
  • シーン理解またはオブジェクト トラッキングを実装
  • 最小 iOS 15.2

プライバシー:

  • カメラ使用時に NSCameraUsageDescription を設定
  • クラウドアップロード時は明示的な 同意を取得

ユーザー体験:

  • オンボーディングで AR 使用方法を説明
  • 不安定なトラッキング時は警告を表示
  • ライティングが暗い環境での代替 UI を提供

審査で よくある拒否理由と対策

理由対策
"ARKit が不安定"3D メッシュ取得タイムアウト、フォールバック UI を実装
"パフォーマンス低下"フレームドロップ時の自動フォールバック
"プライバシー不明"Info.plist の NSCameraUsageDescription を明記
"オブジェクトがめり込む"衝突検出(Physics Body)を実装

第9章:実践プロジェクト「AR 買物アシスタント」

アプリ仕様

  • ユーザーが カメラで商品を指す → リアルタイム認識
  • 商品情報(価格・レビュー・在庫)を 3D パネルで表示
  • タップで詳細ページへ遷移

実装フロー

// AR 買物アシスタント:統合実装
class ShoppingAssistantAR: UIViewController {
    @IBOutlet var arView: ARView!
    let detector = YOLODetector(modelName: "ShoppingProducts")
    let productDB: ProductDatabase = ProductDatabase()
 
    override func viewDidLoad() {
        super.viewDidLoad()
        setupAR()
    }
 
    func setupAR() {
        let configuration = ARWorldTrackingConfiguration()
        configuration.planeDetection = [.horizontal]
        arView.session.run(configuration)
 
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
            self?.detectAndDisplayProducts()
        }
    }
 
    func detectAndDisplayProducts() {
        guard let frame = arView.session.currentFrame else { return }
 
        let image = UIImage(ciImage: CIImage(cvPixelBuffer: frame.capturedImage))
        detector.detectObjects(in: image) { [weak self] detections in
            for (productId, bbox, confidence) in detections.filter({ $0.2 > 0.8 }) {
                if let product = self?.productDB.getProduct(id: productId) {
                    self?.displayProductInfo(product, at: bbox)
                }
            }
        }
    }
 
    func displayProductInfo(_ product: Product, at bbox: CGRect) {
        let screenPoint = CGPoint(x: bbox.midX, y: bbox.midY)
        guard let result = arView.raycast(from: screenPoint, allowing: .estimatedPlane, alignment: .horizontal).first else { return }
 
        let anchor = AnchorEntity(world: result.worldTransform.translation)
 
        // 3D インフォパネルを作成
        let infoPanel = create3DInfoPanel(product: product)
        anchor.addChild(infoPanel)
 
        arView.scene.addAnchor(anchor)
    }
 
    func create3DInfoPanel(product: Product) -> ModelEntity {
        // 簡易実装:立方体にテクスチャをマッピング
        var material = Material()
        // product.imageURL をテクスチャとして適用
 
        let mesh = MeshResource.generatePlane(size: [0.3, 0.4])
        let panel = ModelEntity(mesh: mesh, materials: [material])
 
        return panel
    }
}
 
struct Product {
    let id: String
    let name: String
    let price: Double
    let rating: Double
    let imageURL: URL
}
 
class ProductDatabase {
    func getProduct(id: String) -> Product? {
        // API から商品情報を取得
        return nil
    }
}

第10章:AR アプリの収益化戦略

マネタイズパターン

1. アプリ内課金(IAP)

  • プレミアム フィルター:¥610
  • 広告削除:¥1,220
  • 拡張機能:¥3,060

2. サブスクリプション

  • プレミアム会員:¥980/月
  • 企業向け:¥29,800/年

3. アフィリエイト

  • Amazon Associates で商品リンク

RevenueCat を使用した実装:

// RevenueCat でのサブスク管理
import RevenueCat
 
func setupRevenueCat() {
    Purchases.logLevel = .debug
    Purchases.configure(withAPIKey: "YOUR_REVENUECAT_API_KEY")
 
    Purchases.shared.getCustomerInfo { info, error in
        if info?.entitlements.active["premium"]?.isActive == true {
            // プレミアム機能を有効化
        }
    }
}
 
func purchasePremium() {
    Purchases.shared.getOfferings { offerings, error in
        guard let offering = offerings?.current else { return }
 
        Purchases.shared.purchase(package: offering.availablePackages.first!) { result, error in
            if let transaction = result?.transaction {
                // 購入成功
            }
        }
    }
}

まとめ:次世代 AR×AI アプリの道標

Rork Max を使用した ARKit + Core ML 統合開発は、以下の段階を踏みます:

  1. 基礎構築:ARWorldTrackingConfiguration + シーン理解
  2. 機械学習統合:事前学習済みモデルの Core ML デプロイ
  3. 実装最適化:Metal GPU、フレームレート管理
  4. ユーザー体験:直感的な操作、視覚的フィードバック
  5. 審査・運用:App Store ガイドライン準拠、パフォーマンス監視
  6. 収益化:IAP、サブスク、アフィリエイトの組み合わせ

プレミアム AR アプリは、技術的な完成度 だけでなく、ユーザーの「感動」を設計に組み込むことが成功の鍵です。LiDAR スキャン、リアルタイム物体認識、流暢な 3D アニメーションが調和したとき、初めて「次世代」と呼べるアプリが生まれます。

本ガイドで紹介した技術と戦略を実装し、あなたの AR×AI アプリを App Store で成功させてください。

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

開発ツール2026-07-18
AR で置いたものが翌朝には消えている — ARWorldMap による配置の永続化とリローカライズ設計
Rork Max が生成する AR アプリは、置いた 3D オブジェクトがアプリ再起動で消えます。ARWorldMap の保存タイミング、カスタムアンカーの符号化、リローカライズ待ちの見せ方、成立しない時の逃げ道までを設計として整理しました。
開発ツール2026-07-12
Rork Maxのアプリで、アイコンを気持ちよく動かすsymbolEffect実装メモ
Rork Maxが生成したSwiftアプリで、SF Symbolsをbounce・pulse・variableColor・contentTransitionで動かす実装を、動くコードとOSバージョンの出し分け、そして動かしすぎて後悔した落とし穴つきで整理します。
開発ツール2026-07-09
Rork Max が書いた Swift を、Swift 6 の厳格な並行性検査に通す
Rork Max が生成した SwiftUI アプリを Swift 6 の complete concurrency checking に通した記録です。警告217件をターゲット単位で削り、@MainActor の置き場所と Sendable の壊し方を実測とともに整理しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →