Документация naviar SDK для iOS
Установка
CocoaPods
CocoaPods - это менеджер зависимостей для проектов Cocoa. Более подробную информацию, а также инструкции по использованию и установке, вы можете найти на их сайте. Чтобы интегрировать naviar SDK в ваш проект Xcode с помощью CocoaPods, укажите зависимость VPSNMobile в своем Podfile
:
source '<https://github.com/CocoaPods/Specs.git>'
target 'YOUR PROJECT NAME HERE' do
use_frameworks!
pod 'VPSNMobile'
end
Далее вызовите pod install
из каталога проекта, чтобы создать новый файл .workspace.
Из источников
Вы также можете собрать VPS framework из этого репозитория.
Клонируйте этот репозиторий и вызовите pod install
из каталога проекта, чтобы создать новый файл .workspace. Теперь вы можете построить VPS framework и подключить его к своему проекту.
Примеры
Пример приложения вы можете найти в этом репозитории:
- ExampleAppVPS - интеграция сервиса VPS в реальное приложение для конечного пользователя
Для запуска example проекта склонируйте этот репозиторий и вызовите pod install
из папки ExampleAppVPS для создания файла .workspace.
Видео инструкция по запуску example проекта:
Выбор локации
В данной версии сервиса VPS вам доступно 7 тестовых локаций. Для переключения между ними в example проекте используйте поле currentLocation во ViewController
Применение
Пользовательские разрешения
Добавьте флаги для выдачи доступа к геолокации пользователя и камере в info.plist
. Для устройств с версией iOS 14+ необходимо также добавить TemporaryAuth.
<key>NSCameraUsageDescription</key>
<string></string>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dict>
<key>TemporaryAuth</key>
<string></string>
</dict>
UIKit
- Необходимо определить делегат
ARSCNViewDelegate
и вызывать методvps?.frameUpdated()
каждый кадр - Назначьте конфигурацию по умолчанию с помощью метода
getDefaultConfiguration()
. Если устройство не поддерживается, данная функция вернет nil - Вы можете использовать метод делегата
sessionWasInterrupted
для остановки VPS, когда приложение теряет фокус, и заново запустить его вsessionInterruptionEnded
import VPSNMobile
import UIKit
import ARKit
class Example:UIViewController, ARSCNViewDelegate {
var arview: ARSCNView!
var configuration: ARWorldTrackingConfiguration!
var vps: VPSService?
override func viewDidLoad() {
super.viewDidLoad()
arview.scene = SCNScene()
arview.delegate = self
if let config = VPSBuilder.getDefaultConfiguration() {
configuration = config
} else {
fatalError()
}
let set = Settings(
locationIds: ["polytech"],
recognizeType: .mobile)
VPSBuilder.initializeVPS(arsession: arview.session,
settings: set,
gpsUsage: false,
delegate: self) { (serc) in
self.vps = serc
self.vps?.start()
} loadingProgress: { (pr) in
print("value",pr)
} failure: { (er) in
print("err",er)
}
vps?.start()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
arview.session.run(configuration)
}
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
vps?.frameUpdated()
}
func sessionWasInterrupted(_ session: ARSession) {
vps?.stop()
}
func sessionInterruptionEnded(_ session: ARSession) {
vps?.start()
}
}
extension Example: VPSServiceDelegate {
func positionVPS(pos: ResponseVPSPhoto) {
print("Pos", pos)
}
func error(err: NSError) {
print("err", err)
}
func correctMotionAngle(correct: Bool) {
}
func sending() {
print("Start sending")
}
}
Mobile VPS
Для включения Mobile VPS необходимо выбрать его в настройках recognizeType: .mobile
. В этом случае перед запуском VPS на устройство будет загружена нейросеть. Прогресс установки можно отслеживать в обработчике loadingProgress
. Если модель не удалось загрузить или инициализировать, будет вызван обработчик failure
.
VPSBuilder.initializeVPS(arsession: arview.session,
settings: set,
gpsUsage: false,
delegate: self) { (serc) in
self.vps = serc
} loadingProgress: { (pr) in
print("value",pr)
} failure: { (er) in
print("err",er)
}
RealityKit
Использование RealityKit похоже на использование SceneKit. Вместо использования func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval)
вам нужно использовать func session(_ session: ARSession, didUpdate frame: ARFrame)
делегата ARSessionDelegate
для вызова vps?.frameUpdated()
каждый кадр.
func session(_ session: ARSession, didUpdate frame: ARFrame) {
}
SwiftUI
Для лучшего использования SwiftUI рекомендуется использовать архитектуру MVVM. Пример представлен ниже:
import SwiftUI
import ARKit
import VPSNMobile
struct ContentView: View {
@StateObject var vm = ViewModel()
@State var vpsStarted = false
var body: some View {
VStack {
ARView(vm: vm)
.background(Color.gray)
.cornerRadius(20)
.padding(EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))
Button(vpsStarted ? "stop" : "start") {
vpsStarted ? vm.vps?.stop() : vm.vps?.start()
withAnimation(.linear) {
vpsStarted.toggle()
}
}
.frame(width: 300, height: 50, alignment: .center)
.background(vpsStarted ? Color.red : Color.green)
.cornerRadius(20)
.padding()
}
}
}
class ViewModel:NSObject, ObservableObject, ARSCNViewDelegate, VPSServiceDelegate {
var vps: VPSService?
func initVPS(session:ARSession) {
let set = Settings(
locationIds: ["polytech"],
recognizeType: .mobile)
VPSBuilder.initializeVPS(arsession: session,
settings: set,
gpsUsage: false,
delegate: self) { (vps) in
self.vps = vps
} loadingProgress: { (pr) in
} failure: { (er) in
print("err",er)
}
}
func positionVPS(pos: ResponseVPSPhoto) {
print("POS",pos)
}
func error(err: NSError) {
}
func correctMotionAngle(correct: Bool) {
}
func sending() {
}
}
struct ARView: UIViewRepresentable {
@ObservedObject var vm: ViewModel
func makeUIView(context: Context) -> ARSCNView {
let sceneView = ARSCNView()
sceneView.scene = SCNScene()
sceneView.autoenablesDefaultLighting = true
sceneView.delegate = vm
vm.initVPS(session: sceneView.session)
let config = VPSBuilder.getDefaultConfiguration()!
config.isAutoFocusEnabled = true
sceneView.session.run(config)
return sceneView
}
func updateUIView(_ uiView: ARSCNView, context: Context) {
}
static func dismantleUIView(_ uiView: ARSCNView, coordinator: ()) {
uiView.delegate = nil
}
}