Nearby Interaction - Team-HGD/SniffMEET GitHub Wiki

๐Ÿ“

Ultra Wide Band ์ง€์›ํ•˜๋Š” ๊ธฐ๊ธฐ ๊ฐ„ ๊ฑฐ๋ฆฌ์™€ ๋ฐฉํ–ฅ์„ ๊ฐ์ง€ํ•˜๋Š” ๊ธฐ์ˆ  ๋ฐฉ์‹

๋„์ž… ๋ฐฐ๊ฒฝ

Multipeer Connectivity ์‚ฌ์šฉ ์—†์ด, Name Drop ๋ฐฉ์‹์˜ ๊ธฐ๋Šฅ์„ ๋„์ž…ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์„ ์กฐ์‚ฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

Nearby Interaction์ด๋‚˜ NFC ๋ฐฉ์‹์„ ํ™œ์šฉํ•ด ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๊ณ ,

๊ทธ ์ค‘ Nearby Interaction ๋ฐฉ์‹์— ๋Œ€ํ•ด ์ •๋ฆฌํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

๊ฐœ์š”

Nearby Interaction์€ U1 ์นฉ์„ ํƒ‘์žฌํ•˜๊ณ  ์žˆ๋Š” ๊ธฐ๊ธฐ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ์™€ ๋ฐฉํ–ฅ์„ ๊ฐ์ง€ํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

iPhone 11+ Xcode 12+ iOS 14+

์„ค๋ช…

ํ•ต์‹ฌ ๊ธฐ๋Šฅ

Nearby Interaction

U1 ์นฉ์ด ํƒ‘์žฌ๋œ ๊ธฐ๊ธฐ์˜ ์œ„์น˜๋ฅผ ๊ณ ์ฃผํŒŒ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด ํš๋“ํ•œ๋‹ค.

์ƒํ˜ธ ์ž‘์šฉ์— ์ฐธ์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๊ทผ์ ‘ํ•œ ์žฅ์น˜๋Š” ์•ฑ์„ ์‹คํ–‰ํ•˜๊ณ  ์œ„์น˜์™€ ์žฅ์น˜ ํ† ํฐ์„ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•œ๋‹ค.

์•ฑ์ด ํฌ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰๋˜๋ฉด ํ”ผ์–ด์˜ ๋ฐฉํ–ฅ๊ณผ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฏธํ„ฐ ๋‹จ์œ„๋กœ ๋ณด๊ณ ํ•ด ์œ„์น˜๋ฅผ ์ƒํ˜ธ์ž‘์šฉ ์„ธ์…˜์— ์•Œ๋ฆฐ๋‹ค.

  • ๋””๋ฐ”์ด์Šค ๊ฐ์ง€ : ์ฃผ๋ณ€ ๋‹ค๋ฅธ iOS ๊ธฐ๊ธฐ๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  ๊ฐ์ง€, ์ด๋ฅผ ํ†ตํ•ด ์ฃผ๋ณ€์— ์žˆ๋Š” ๊ธฐ๊ธฐ ์‹๋ณ„ํ•˜๊ณ  ์„ ํƒ ๊ฐ€๋Šฅ
  • ๋ฐ์ดํ„ฐ ๊ตํ™˜ : ๊ธฐ๊ธฐ๋“ค ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ๊ตํ™˜ ๊ฐ€๋Šฅ (ํ…์ŠคํŠธ, ์ด๋ฏธ์ง€, ํŒŒ์ผ ๋“ฑ)
  • ์ƒํ˜ธ ์ž‘์šฉ : ๊ธฐ๊ธฐ๋“ค๋ผ๋ฆฌ ์„œ๋กœ ์ƒํ˜ธ์ž‘์šฉ ๊ฐ€๋Šฅ
  • ์œ„์น˜ ์ •๋ณด : ์ƒ๋Œ€ ๊ธฐ๊ธฐ์˜ ๊ทผ์ ‘ํ•œ ์œ„์น˜ ์ •๋ณด ์–ป๊ธฐ ๊ฐ€๋Šฅ

Nearby Interaction ์ƒ˜ํ”Œ ์ฝ”๋“œ

https://developer.apple.com/documentation/nearbyinteraction/implementing-interactions-between-users-in-close-proximity

ํ•ด๋‹น ์ƒ˜ํ”Œ์ฝ”๋“œ์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ์ž๋Š” Bluetooth ํ†ตํ•ด ๊ทผ์ฒ˜ ๋””๋ฐ”์ด์Šค๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ  ์ƒํ˜ธ์ž‘์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • TranData NSCoding ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ. ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด ์ธ์ฝ”๋”ฉ ๋””์ฝ”๋”ฉํ•  ์ˆ˜์žˆ์œผ๋ฉฐ ๋ฐœ๊ฒฌ๋œ ๊ทผ์ฒ˜ ๋””๋ฐ”์ด์Šค์˜ ๊ฒ€์ƒ‰ ํ† ํฐ / ์ถฉ๋Œ ์—ฌ๋ถ€ / ๋””๋ฐ”์ด์Šค ๊ด€๋ จ ํ‚ค์›Œ๋“œ ๋ชฉ๋ก / ๋””๋ฐ”์ด์Šค ์†Œ์œ ์ž ๋ณ„๋ช… ๋ฐ ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ํฌํ•จํ•œ๋‹ค.
  • NISessionManager Nearby Interaction ์„ธ์…˜ ๊ด€๋ฆฌํ•˜๋Š” ํด๋ž˜์Šค. ObservableObject ํ”„๋กœ์ฝ”ํ†จ์„ ์ค€์ˆ˜ํ•˜๋ฉฐ, ์†์„ฑ์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฒŒ์‹œํ•ด ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ํ•ด๋‹น ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ด€์ฐฐํ•˜๊ณ  ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
  • ์ƒ˜ํ”Œ ์ฝ”๋“œ ๋ถ„์„
    • connectedPeers: ํ˜„์žฌ ์—ฐ๊ฒฐ๋œ ๊ทผ์ฒ˜ ๋””๋ฐ”์ด์Šค๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” MCPeerID ๊ฐ์ฒด์˜ ๋ฐฐ์—ด.
    • viewDidLoad() - startup() - ์„ธ์…˜ ์ƒ์„ฑ
    • ํ˜„์žฌ ์—ฐ๊ฒฐ๋œ ๋””๋ฐ”์ด์Šค ์กด์žฌํ•˜๊ณ , MPCSession์ด ์กด์žฌํ•œ๋‹ค๋ฉด ์„ธ์…˜ ํ† ํฐ ์ง€์ •.
    • ๊ณต์œ ๋œ ํ† ํฐ์ด ์—†๋‹ค๋ฉด, shareMyDiscoveryToken()์œผ๋กœ ํ† ํฐ ๊ณต์œ 
    • ๊ณต์œ ๋œ ํ† ํฐ์ด ์—†๋‹ค๋ฉด, ํƒ์ƒ‰์ค‘์ธ ์ƒํƒœ์ด๋ฏ€๋กœ ๊ด€๋ จ ์• ๋‹ˆ๋ฉ”์ด์…˜? ํ‘œ์‹œํ•˜๊ณ  MPC ์‹œ์ž‘

Nearby Interaction์„ ํ†ตํ•œ Namedrop ํ๋ฆ„

  1. NISession ์ดˆ๊ธฐํ™” ๋ฐ ์„ค์ •
    • ๊ธฐ๊ธฐ ๊ฐ„ ๊ทผ์ ‘ ๊ฐ์ง€ ์„ธ์…˜์„ ์ƒ์„ฑํ•˜๊ณ , ์—ฐ๊ฒฐ ์ƒํƒœ์™€ ํ”„๋กœํ•„ ๊ณต์œ  ์ด๋ฒคํŠธ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • NISession์€ ์ฃผ๋ณ€ ๊ธฐ๊ธฐ์™€ ์—ฐ๊ฒฐํ•˜๊ณ  ์ •๋ณด๋ฅผ ์ฃผ๊ณ ๋ฐ›๊ธฐ ์œ„ํ•œ ๊ธฐ๋ณธ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
  2. Discovery Token ๊ตํ™˜
    • ๊ฐ ๊ธฐ๊ธฐ์—๋Š” ๊ณ ์œ ํ•œ discoveryToken์ด ์žˆ์–ด Nearby Interaction์˜ ๊ฐ ๊ธฐ๊ธฐ๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
    • ๋‘ ๊ธฐ๊ธฐ๊ฐ€ ์„œ๋กœ์˜ discoveryToken์„ ๊ตํ™˜ํ•˜์—ฌ, ๋‘ ๊ธฐ๊ธฐ ๊ฐ„์˜ ์„ธ์…˜์ด ํ˜•์„ฑ๋˜๋ฉด Nearby Interaction์„ ํ†ตํ•ด ๊ฑฐ๋ฆฌ ๋ฐ ๋ฐฉํ–ฅ ์ •๋ณด๋ฅผ ๋ฐ›์•„ ๋ฉ”์ดํŠธ ๋งค์นญ์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • discoveryToken์„ ๊ตํ™˜ํ•˜๊ธฐ ์œ„ํ•ด Multipeer Connectivity ์‚ฌ์šฉ์ด ํ•„์š”ํ•˜๋‹ค.
  3. ๊ฑฐ๋ฆฌ ๋ฐ ๋ฐฉํ–ฅ ์ •๋ณด ์—…๋ฐ์ดํŠธ
    • ๋‘ ๊ธฐ๊ธฐ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ ๋ฐ ๋ฐฉํ–ฅ ์ •๋ณด๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜์—ฌ, ํŠน์ • ๋ฐ˜๊ฒฝ ๋‚ด์— ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ํ”„๋กœํ•„์„ ๊ณต์œ ํ•˜๋Š” ๋“ฑ์˜ ์กฐ๊ฑด์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  4. ํ”„๋กœํ•„ ๊ณต์œ  ๋ฐ ๋ฉ”์ดํŠธ ์š”์ฒญ ์ „์†ก
    • ๋‘ ๊ธฐ๊ธฐ๊ฐ€ ํŠน์ • ๊ฑฐ๋ฆฌ ๋ฐ ๋ฐฉํ–ฅ์œผ๋กœ ๊ทผ์ ‘ํ•ด ์žˆ์œผ๋ฉด ๋ฐ˜๋ ค๋™๋ฌผ ํ”„๋กœํ•„์„ ์ƒ๋Œ€๋ฐฉ ๊ธฐ๊ธฐ์— ์ „์†กํ•˜์—ฌ ํ™”๋ฉด์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
    • ์ƒ๋Œ€๋ฐฉ์ด ์š”์ฒญ์„ ์ˆ˜๋ฝํ•˜๋ฉด, ๋ฉ”์ดํŠธ๊ฐ€ ๋˜์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์•ฑ ๋‚ด ๋ฉ”์ดํŠธ ๋ชฉ๋ก์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

Nearby Interaction์„ ํ™œ์šฉํ•œ ์•ฑ ์ ์šฉ ์‹œ ์œ ์˜์ 

  • ํ˜ธํ™˜ ๊ธฐ๊ธฐ: Nearby Interaction์€ U1 ์นฉ์„ ๊ฐ–์ถ˜ iPhone 11 ์ด์ƒ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฑฐ๋ฆฌ ์กฐ๊ฑด: ๋„ˆ๋ฌด ๊ฐ€๊นŒ์ด ๋Œ€์ง€ ์•Š์•„๋„ ์•ˆ์ •์ ์ธ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅํ•œ ๋ฐ˜๊ฒฝ ์กฐ๊ฑด์„ ์„ค์ •ํ•˜์—ฌ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.
  • ์‹œ๊ฐ์  ํ”ผ๋“œ๋ฐฑ: ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ธฐ๊ธฐ๋ฅผ ๋งž๋Œ€๊ฑฐ๋‚˜ ๊ทผ์ฒ˜์— ๋†“๋„๋ก ์‹œ๊ฐ์  ์•ˆ๋‚ด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•˜๋‹ค.

์‚ฌ์šฉ๋ฒ•

1. NISession ์ดˆ๊ธฐํ™” ๋ฐ ์„ค์ •

๋จผ์ € NISession์„ ์ƒ์„ฑํ•˜๊ณ , ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด NISessionDelegate๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์„ธ์…˜์„ ์‹œ์ž‘ํ•˜๋ฉด ์‚ฌ์šฉ์ž์—๊ฒŒ Nearby Interaction ๊ธฐ๋Šฅ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์•ˆ๋‚ด๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import NearbyInteraction

class NearbyInteractionManager: NSObject, NISessionDelegate {
    private var niSession: NISession?

    func startSession() {
        niSession = NISession()
        niSession?.delegate = self
        niSession?.run(NINearbyPeerConfiguration(peerToken: try! niSession!.discoveryToken!))
    }

    func session(_ session: NISession, didInvalidateWith error: Error) {
        print("Session was invalidated: \(error.localizedDescription)")
        // ์žฌ์‹œ๋„ ๋กœ์ง ๋˜๋Š” ์˜ค๋ฅ˜ ์•ˆ๋‚ด
    }

    func sessionWasSuspended(_ session: NISession) {
        print("Session was suspended")
        // ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์„ธ์…˜ ์ผ์‹œ ์ •์ง€ ์ฒ˜๋ฆฌ
    }

    func sessionSuspensionEnded(_ session: NISession) {
        print("Session suspension ended")
        // ํ•„์š” ์‹œ ์„ธ์…˜ ์žฌ๊ฐœ
    }
}

2. Discovery Token ๊ตํ™˜

Nearby Interaction์€ ๊ฐ ๊ธฐ๊ธฐ๊ฐ€ ์„œ๋กœ์˜ discoveryToken์„ ์•Œ์•„์•ผ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด, Bluetooth๋‚˜ ์ธํ„ฐ๋„ท์„ ํ†ตํ•œ ๋ณ„๋„ ๋ฐฉ๋ฒ•์œผ๋กœ ํ† ํฐ์„ ๊ตํ™˜ํ•œ ํ›„, ์„ธ์…˜์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

func startPeerSession(with peerToken: NIDiscoveryToken) {
    let config = NINearbyPeerConfiguration(peerToken: peerToken)
    niSession?.run(config)
}

3. ๊ฑฐ๋ฆฌ ๋ฐ ๋ฐฉํ–ฅ ์ •๋ณด ์—…๋ฐ์ดํŠธ

Nearby Interaction์€ ๋‘ ๊ธฐ๊ธฐ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ ๋ฐ ๋ฐฉํ–ฅ ์ •๋ณด๋ฅผ NISessionDelegate์˜ session(_:didUpdate:) ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ์ผ์ • ๊ฑฐ๋ฆฌ ์•ˆ์— ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฉ”์ดํŠธ ์š”์ฒญ์„ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

func session(_ session: NISession, didUpdate nearbyObjects: [NINearbyObject]) {
    guard let nearbyObject = nearbyObjects.first else { return }
    // ๊ฑฐ๋ฆฌ์™€ ๋ฐฉํ–ฅ ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ฉ”์ดํŠธ ์š”์ฒญ ํ‘œ์‹œ ์กฐ๊ฑด์„ ์„ค์ •
}

func showMateRequest(for nearbyObject: NINearbyObject) {
    // ํ”„๋กœํ•„ ์ •๋ณด ๊ณต์œ  ๋ฐ ๋ฉ”์ดํŠธ ์š”์ฒญ UI ํ‘œ์‹œ
}

4. ํ”„๋กœํ•„ ๊ณต์œ  ๋ฐ ๋ฉ”์ดํŠธ ์š”์ฒญ ์ˆ˜๋ฝ

๊ธฐ๊ธฐ๊ฐ€ ๊ทผ์ ‘ํ•ด ํŠน์ • ๊ฑฐ๋ฆฌ ์ด๋‚ด์— ๋“ค์–ด์˜ค๋ฉด showMateRequest(for:) ๋ฉ”์„œ๋“œ์—์„œ ๋ฉ”์ดํŠธ ์š”์ฒญ ํ™”๋ฉด์„ ๋„์šฐ๊ณ , ์ˆ˜๋ฝ ์‹œ ํ”„๋กœํ•„ ๊ตํ™˜๊ณผ ๋ฉ”์ดํŠธ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

func showMateRequest(for nearbyObject: NINearbyObject) {
    // ์š”์ฒญ ์•Œ๋ฆผ ๋˜๋Š” ํŒ์—… ํ‘œ์‹œ
    // ์•Œ๋ฆผ์„ ํ˜„์žฌ ํ™”๋ฉด์— ํ‘œ์‹œ
}

func confirmMateRequest() {
    // ์ˆ˜๋ฝ ์‹œ ํ”„๋กœํ•„ ๋ฐ ๋ฉ”์ดํŠธ ๊ด€๊ณ„ ์ •๋ณด ์ €์žฅ
    saveMateInformation()
}

Ref.


https://developer.apple.com/documentation/nearbyinteraction/

https://developer.apple.com/design/human-interface-guidelines/nearby-interactions

https://developer.apple.com/documentation/nearbyinteraction/initiating-and-maintaining-a-session

https://developer.apple.com/kr/videos/play/wwdc2022/10008/

https://m.blog.naver.com/jasonrewriter/222132246904

https://bokoo.tistory.com/entry/iOS-NearbyInteraction%EB%9E%80

โš ๏ธ **GitHub.com Fallback** โš ๏ธ