https://github.com/dmojdehi/SwiftGlobe/blob/master/src/SwiftGlobe.swift

1️⃣ 監聽控制器連線 / 辨識遙控器型號

檔案Syncnext tvOS/App/PlayerKSView/Player/registerForGameControllerNotifications.swift

import GameController

class GameControllerObserver {
    init() {
        // 連線通知
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleControllerDidConnectNotification(notification:)),
            name: NSNotification.Name.GCControllerDidConnect,
            object: nil
        )
        // 斷線通知
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleControllerDidDisconnectNotification(notification:)),
            name: NSNotification.Name.GCControllerDidDisconnect,
            object: nil
        )
    }

    @objc private func handleControllerDidConnectNotification(notification: NSNotification) {
        // 取得已連線的 GCController
        GameControllerStatus.gameController = notification.object as? GCController

        // 依照產品類別決定型別
        if let controller = GameControllerStatus.gameController {
            switch controller.productCategory {
            case "Siri Remote (1st Generation)":
                GameControllerStatus.gameControllerType = .Remote1
                // 需要取得 microGamepad 才能讀取 D‑Pad
                controller.microGamepad?.reportsAbsoluteDpadValues = true

            case "Siri Remote (2nd Generation)":
                GameControllerStatus.gameControllerType = .Remote2

            default:
                // 其他類型(例如 MFi 控制器)可自行處理
                GameControllerStatus.gameControllerType = .MFi
            }
        }
    }

    @objc private func handleControllerDidDisconnectNotification(notification: NSNotification) {
        // 釋放資源或重置狀態
        GameControllerStatus.gameController = nil
        GameControllerStatus.gameControllerType = .Remote1   // 依需求調整
    }
}


2️⃣ 控制器狀態模型(集中存放)

檔案Syncnext tvOS/Status/Normal/GameControllerStatus.swift

import GameController

/// 用來全域保存目前連線中控制器的資訊
class GameControllerStatus {
    /// 控制器的型別
    enum GameControllerType { case MFi, Remote1, Remote2 }

    /// 目前已連線的 GCController(可為 nil)
    static var gameController: GCController?

    /// 目前偵測到的型別,預設為 .Remote1(可自行調整預設)
    static var gameControllerType: GameControllerType = .Remote1
}


3️⃣ 針對不同遙控器型號做按鍵映射

檔案Syncnext tvOS/App/PlayerKSView/Player/ExtensionRemoteController.swift

import UIKit
import GameController

class ExtensionRemoteController: UIViewController {

    // … 其他程式碼 …

    override func viewDidLoad() {
        super.viewDidLoad()

        // 依型別決定不同的按鍵處理方式
        if GameControllerStatus.gameControllerType == .Remote1 {
            // ==================== 傳統遙控器 ====================
            // 需要在 pressesBegan / pressesEnded 裡自行解析按鍵
            // 這裡只示範取得 D‑Pad 的值(見第 4 點)

        } else {
            // ==================== 新遙控器(Play/Pause) ====================
            // 使用 UITapGestureRecognizer 只要支援 .playPause
            let pressRecognizer = UITapGestureRecognizer()
            pressRecognizer.allowedPressTypes = [NSNumber(value: UIPress.PressType.playPause.rawValue)]
            view.addGestureRecognizer(pressRecognizer)
        }
    }

    // MARK: - 例:處理 GCController 的按鍵
    override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
        guard let press = presses.first else { return }

        switch press.type {
        case .menu:        // 例:菜單鍵
            // 你的處理...
            break

        case .playPause:   // 例:播放/暫停鍵
            // 你的處理...
            break

        default:
            break
        }
    }
}


4️⃣ 傳統遙控器的 D‑Pad 方向判斷

檔案:同上(ExtensionRemoteController.swift

// 只在是 Remote1 時才需要判斷 D‑Pad
if GameControllerStatus.gameControllerType == .Remote1,
   let microGamepad = GameControllerStatus.gameController?.microGamepad,
   let xAxis = microGamepad.dpad.xAxis.value {
    // xAxis 介於 -1 ~ 1,超過阈值視為「按下」
    if xAxis > 0.55 {
        touchPressType = .touchRight   // 向右按下
    } else if xAxis < -0.55 {
        touchPressType = .touchLeft    // 向左按下
    }
}


5️⃣ Info.plist 宣告支援的控制器 Profile

檔案Syncnext tvOS/Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
        "<http://www.apple.com/DTDs/PropertyList-1.0.dtd>">
<plist version="1.0">
<dict>
    <!-- 其他設定 ... -->

    <!-- 支援的遊戲控制器 Profile -->
    <key>GCSupportedGameControllers</key>
    <array>
        <!-- 1st‑Gen Siri Remote -->
        <dict>
            <key>ProfileName</key>
            <string>MicroGamepad</string>
        </dict>

        <!-- 2nd‑Gen Siri Remote -->
        <dict>
            <key>ProfileName</key>
            <string>ExtendedGamepad</string>
        </dict>

        <!-- 方向式遙控器(D‑Pad) -->
        <dict>
            <key>ProfileName</key>
            <string>DirectionalGamepad</string>
        </dict>
    </array>

    <!-- 其他設定 ... -->
</dict>
</plist>