Slide 1

Slide 1 text

AKKEY / AKIO ITAYA ૑଄తͳ visionOS ΞϓϦ։ൃज़ iOS Engineer Meetup in Money Forward Persona Λ׆༻

Slide 2

Slide 2 text

Apple Vision Pro ઐ༻ Ξόλʔػೳ Persona

Slide 3

Slide 3 text

Persona Anywhere

Slide 4

Slide 4 text

Persona Viewer

Slide 5

Slide 5 text

Persona & Camera AVFoundation Persona

Slide 6

Slide 6 text

Persona & Camera AVFoundation ARKit Persona Main Camera visionOS 2

Slide 7

Slide 7 text

final class PersonaProvider: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate { private let session = AVCaptureSession() private override init() { super.init() guard let device = AVCaptureDevice.systemPreferredCamera, let input = try? AVCaptureDeviceInput(device: device) else { return } #if targetEnvironment(simulator) #else session.addInput(input) #endif } }

Slide 8

Slide 8 text

final class PersonaProvider: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate { private let session = AVCaptureSession() private override init() { super.init() guard let device = AVCaptureDevice.systemPreferredCamera, let input = try? AVCaptureDeviceInput(device: device) else { return } #if targetEnvironment(simulator) #else session.addInput(input) #endif } }

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

final class PersonaProvider: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate { private let session = AVCaptureSession() private override init() { super.init() guard let device = AVCaptureDevice.systemPreferredCamera, let input = try? AVCaptureDeviceInput(device: device) else { return } #if targetEnvironment(simulator) #else session.addInput(input) #endif let output = AVCaptureVideoDataOutput() output.setSampleBufferDelegate(self, queue: DispatchQueue(label: "camera_queue")) session.addOutput(output) } }

Slide 12

Slide 12 text

final class PersonaProvider: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate { private let session = AVCaptureSession() private override init() { super.init() guard let device = AVCaptureDevice.systemPreferredCamera, let input = try? AVCaptureDeviceInput(device: device) else { return } #if targetEnvironment(simulator) #else session.addInput(input) #endif let output = AVCaptureVideoDataOutput() output.setSampleBufferDelegate(self, queue: DispatchQueue(label: "camera_queue")) session.addOutput(output) } func captureOutput(_ output: AVCaptureOutput, didOutput: CMSampleBuffer, from: AVCaptureConnection) { guard let imageBuffer = CMSampleBufferGetImageBuffer(didOutput) else { return } let ciImage = CIImage(cvImageBuffer: imageBuffer) let uiImage = UIImage(ciImage: ciImage) } }

Slide 13

Slide 13 text

Multipeer Connectivity Multipeer Connectivity Framework

Slide 14

Slide 14 text

final class SessionContainer: NSObject, ObservableObject { private let session = MCSession(peer: peerId) private let nearbyServiceBrowser = MCNearbyServiceBrowser(peer: peerId, serviceType: serviceType) override init() { super.init() session.delegate = self nearbyServiceBrowser.delegate = self } } extension SessionContainer: MCNearbyServiceBrowserDelegate { } extension SessionContainer: MCSessionDelegate { }

Slide 15

Slide 15 text

final class SessionContainer: NSObject, ObservableObject { private let session = MCSession(peer: peerId) private let nearbyServiceBrowser = MCNearbyServiceBrowser(peer: peerId, serviceType: serviceType) override init() { super.init() session.delegate = self nearbyServiceBrowser.delegate = self } } extension SessionContainer: MCNearbyServiceBrowserDelegate { func browser(_ browser: MCNearbyServiceBrowser, foundPeer: MCPeerID, withDiscoveryInfo: [String: String]?) { browser.invitePeer(foundPeer, to: session, withContext: nil, timeout: 30) } } extension SessionContainer: MCSessionDelegate { }

Slide 16

Slide 16 text

final class SessionContainer: NSObject, ObservableObject { private let session = MCSession(peer: peerId) private let nearbyServiceBrowser = MCNearbyServiceBrowser(peer: peerId, serviceType: serviceType) private var selectedPeer: MCPeerID? override init() { super.init() session.delegate = self nearbyServiceBrowser.delegate = self } } extension SessionContainer: MCNearbyServiceBrowserDelegate { func browser(_ browser: MCNearbyServiceBrowser, foundPeer: MCPeerID, withDiscoveryInfo: [String: String]?) { browser.invitePeer(foundPeer, to: session, withContext: nil, timeout: 30) } } extension SessionContainer: MCSessionDelegate { func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) { selectedPeer = session.connectedPeers.first } }

Slide 17

Slide 17 text

final class SessionContainer: NSObject, ObservableObject { private let session = MCSession(peer: peerId) private let nearbyServiceBrowser = MCNearbyServiceBrowser(peer: peerId, serviceType: serviceType) private var selectedPeer: MCPeerID? override init() { super.init() session.delegate = self nearbyServiceBrowser.delegate = self PersonaProvider.shared.updateFrame = { [weak self] image in if let self, let selectedPeer, let data = image.jpegData(compressionQuality: quality) { try? session.send(data, toPeers: [selectedPeer], with: .reliable) } } } } extension SessionContainer: MCNearbyServiceBrowserDelegate { func browser(_ browser: MCNearbyServiceBrowser, foundPeer: MCPeerID, withDiscoveryInfo: [String: String]?) { browser.invitePeer(foundPeer, to: session, withContext: nil, timeout: 30) } } extension SessionContainer: MCSessionDelegate { func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) { selectedPeer = session.connectedPeers.first } }

Slide 18

Slide 18 text

Thank you !!