Warsztaty i wykłady z oprogramowania

Samouczki i rozwój oprogramowania => Inne => Wątek zaczęty przez: TehekCom w Mar 02, 2026, 10:55 AM

Tytuł: Swift z iOS 19 w (2026) Vision Pro i Spatial Computing (VisionOS + SwiftUI...)
Wiadomość wysana przez: TehekCom w Mar 02, 2026, 10:55 AM
Wstęp
VisionOS 2 wraz z iOS 19, ARKit 8, RealityKit 2 i Entity Component System (ECS) stały się jeszcze silniejsze. W 2026 roku aplikacje spatial nie służą już tylko do gier; są używane w edukacji, designie, handlu detalicznym i produktywności.
W tym przewodniku stworzymy od zera Aplikację do Wirtualnego Umieszczania Mebli (AR Furniture Placement):

Wymagania
Xcode 17+ (VisionOS SDK), symulator Vision Pro lub urządzenie
Nowy projekt → Aplikacja VisionOS (z opcją Immersive Space)

1. Struktura Projektu

CytatFurnitureAR/
├── Models/
│  └── FurnitureEntity.swift
├── Views/
│  ├── ContentView.swift
│  ├── PlacementView.swift
│  └── ImmersiveView.swift
├── Components/
│  └── FurnitureComponent.swift
└── FurnitureARApp.swift

2. Entity i Component w RealityKit
Models/FurnitureEntity.swift

import RealityKit
import SwiftUI

struct FurnitureEntity: Entity, HasModel, HasAnchoring {
    var model: ModelComponent?

    init(usdzName: String) {
        super.init()

        guard let modelURL = Bundle.main.url(forResource: usdzName, withExtension: "usdz") else {
            fatalError("Plik USDZ nie znaleziony: \(usdzName)")
        }

        do {
            let model = try ModelEntity.loadModel(contentsOf: modelURL)
            model.generateCollisionShapes(recursive: true)
            model.components.set(CollisionComponent(shapes: [.generateBox(size: 1.0)]))
            model.components.set(InputTargetComponent())

            self.addChild(model)
            self.model = model.components[ModelComponent.self]

        } catch {
            print("Błąd ładowania modelu: \(error)")
        }
    }

    @MainActor required init() {
        fatalError("init() has not been implemented")
    }
}

3. Widok Umieszczania (SwiftUI + ARView)
Views/PlacementView.swift
import SwiftUI
import RealityKit
import ARKit

struct PlacementView: View {
    @State private var arView = ARView(frame: .zero)
    @State private var selectedFurniture: String? = nil
    @State private var placedEntities: [Entity] = []

    var body: some View {
        ZStack {
            ARViewContainer(arView: $arView, placedEntities: $placedEntities)
                .ignoresSafeArea()

            VStack {
                Spacer()
                HStack(spacing: 20) {
                    ForEach(["sofa", "stół", "lampa"], id: \.self) { item in
                        Button {
                            selectedFurniture = item
                        } label: {
                            Text(item.capitalized)
                                .padding()
                                .background(Color.blue.opacity(0.8))
                                .clipShape(Capsule())
                        }
                    }
                }
            }
            .padding(.bottom, 40)
        }
        .onAppear {
            setupAR()
        }
        .gesture(
            DragGesture()
                .targetedToAnyEntity()
                .onChanged { value in
                    value.entity.position = value.convert(value.location3D, from: .local, to: .scene)
                }
        )
        .gesture(
            TapGesture()
                .targetedToAnyEntity()
                .onEnded { value in
                    if let furniture = selectedFurniture {
                        let newEntity = FurnitureEntity(usdzName: furniture)
                        newEntity.position = value.convert(value.location3D, from: .local, to: .scene)
                        arView.scene.addAnchor(newEntity)
                        placedEntities.append(newEntity)
                        selectedFurniture = nil
                    }
                }
        )
    }

    func setupAR() {
        let config = ARWorldTrackingConfiguration()
        config.planeDetection = [.horizontal, .vertical]
        config.environmentTexturing = .automatic
        arView.session.run(config)

        // Wizualizacja płaszczyzn
        arView.debugOptions = [.showFeaturePoints, .showAnchorOrigins]
    }
}

struct ARViewContainer: UIViewRepresentable {
    @Binding var arView: ARView
    @Binding var placedEntities: [Entity]

    func makeUIView(context: Context) -> ARView {
        return arView
    }

    func updateUIView(_ uiView: ARView, context: Context) {}
}

4. Immersive Space (Pełny Tryb VR)
Dodaj ImmersiveSpace w FurnitureARApp.swift:
import SwiftUI
import RealityKit

@main
struct FurnitureARApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }

        ImmersiveSpace(id: "ImmersiveFurniture") {
            ImmersiveView()
        }
        .immersionStyle(selection: .constant(.mixed), in: .mixed)
    }
}

struct ContentView: View {
    @Environment(\.openImmersiveSpace) var openImmersiveSpace

    var body: some View {
        VStack(spacing: 40) {
            Text("Wirtualne Umieszczanie Mebli")
                .font(.largeTitle)

            Button("Rozpocznij w Trybie Immersyjnym") {
                Task {
                    await openImmersiveSpace(id: "ImmersiveFurniture")
                }
            }
            .buttonStyle(.borderedProminent)
        }
    }
}

struct ImmersiveView: View {
    var body: some View {
        RealityView { content in
            // Tutaj możesz dodać środowisko 360° lub dodatkowe entity
            if let skybox = try? EnvironmentResource.load(named: "skybox") {
                content.environment = skybox
            }

            // Przykładowy anchor
            let anchor = AnchorEntity(world: [0, 0, -3])
            anchor.addChild(FurnitureEntity(usdzName: "sofa"))
            content.add(anchor)
        }
    }
}

5. Dodawanie Modeli USDZ
Xcode → Assets → + → Add Files → Przeciągnij pliki .usdz (na przykład przykładowe modele Apple lub własne eksportowane z Blendera).
Przykładowe źródła: Apple AR Quick Look Gallery lub darmowe modele USDZ z Sketchfab.

6. Zaawansowane Funkcje (2026)