Multipeer Connectivity не работает после обновления Xcode 11 - PullRequest
1 голос
/ 25 октября 2019

Я пытаюсь создать базовое приложение для отправки сообщений между соседними устройствами iOS с помощью Multipeer Connectivity Framework. Я перепробовал много учебных пособий, но, похоже, в Xcode 11 просмотр соседних устройств и прием запросов не работает, как это было раньше.

Вот мой контроллер представления и методы делегата:

import UIKit
import MultipeerConnectivity

class ViewController: UIViewController,MCSessionDelegate,MCBrowserViewControllerDelegate {

var peerID: MCPeerID?
var session: MCSession?

override func viewDidLoad() {
   super.viewDidLoad()
   peerID = MCPeerID(displayName: UIDevice.current.name)
   session = MCSession(peer: peerID!, securityIdentity: nil, encryptionPreference: .none)
   session!.delegate = self
}

func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
    switch state {
    case .connected: print("Connected to \(peerID.displayName)")
    case .connecting: print("Connecting: \(peerID.displayName)")
    case .notConnected: print("Not Connected: \(peerID.displayName)")
    default: print("")
    }
}

func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {

}

func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {

}

func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {

}

func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) {

}

func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
    browserViewController.dismiss(animated: true, completion: nil)
}

func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
    browserViewController.dismiss(animated: true, completion: nil)
}

}

IВ пользовательский интерфейс добавлены 2 кнопки: одна для хостинга, а другая для присоединения. Вот методы:

@IBAction func hostBtnTapped(_ sender: Any) {
    hostSession()
}

@IBAction func joinBtnTapped(_ sender: Any) {
    joinSession()
}

Они вызывают:

func hostSession() {
    let advertiser = MCAdvertiserAssistant(serviceType: "mg-testing", discoveryInfo: nil, session: session!)
    advertiser.start()
}
func joinSession() {
    let browser = MCBrowserViewController(serviceType: "mg-testing", session: session!)
    browser.delegate = self
    self.present(browser, animated: true, completion: nil)
}

Когда я компилирую и запускаю его, все выглядит хорошо. Я нажимаю «Хост» на моем первом устройстве и вхожу в режим «Присоединиться» на моем втором устройстве (отображается MCBrowserViewController), но присоединяющееся устройство никогда не обнаруживает хост-устройство. В консоли нет вывода и нет ошибок. Индикатор «Поиск ...» на присоединяющемся устройстве горит постоянно, и никакие устройства поблизости не отображаются. Что может быть причиной этого? Как я могу решить это? Я использую Xcode 11.0 и iOS 12 и 13.

Ответы [ 2 ]

1 голос
/ 27 октября 2019

Кажется, MCAdvertiserAssistant и MCBrowserViewController не обновлены для последних версий iOS и Swift, поэтому они не работают должным образом.

Я решил это, используя MCNearbyServiceAdvertiser вместо MCAdvertiserAssistantи MCNearbyServiceBrowser вместо MCBrowserViewController. Обратите внимание, что при использовании этих классов вам нужно будет самостоятельно выполнять основные операции, такие как перечисление найденных устройств, отображение и обработка оповещений о приглашениях и т. Д.

Вы можете использовать эти классы, как показано ниже.

Определение:

 var advertiser: MCNearbyServiceAdvertiser!
 var browser: MCNearbyServiceBrowser!

Инициализация:

advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "my-test")
browser = MCNearbyServiceBrowser(peer: peerID, serviceType: "my-test")

Назначение делегатов и запуск:

advertiser.delegate = self
advertiser.startAdvertisingPeer()
browser.delegate = self
browser.startBrowsingForPeers()
0 голосов
/ 28 октября 2019

Судя по ответу моего предшественника, самая большая проблема - MCAdvertiserAssistant. MCBrowserViewController отлично работает для меня.

Если у вас есть код, который должен работать на основе MCAdvertiserAssistant и MCBrowserViewController, попробуйте заменить MCAdvertiserAssistant на MCNearbyServiceAdvertiser.

Такэто все, что вам нужно, если вы, например, работаете над Project 25 за 100 дней Swift Пола Хадсона. (Что я и сделал, когда мне нужно было найти решение проблемы)

var advertiser: MCNearbyServiceAdvertiser!
advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "my-test")
advertiser.delegate = self
advertiser.startAdvertisingPeer()

Добавьте MCNearbyServiceAdvertiserDelegate в список протоколов и внедрите метод делегата:

func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
        invitationHandler(true, mcSession)
    }

Этобудет просто принимать каждое соединение, но этого достаточно, чтобы оно работало.

Для дальнейшего изучения: Кажется, проблема в новом шаблоне Xcode и новом UIApplicationSceneManifest в info.plist иновый SceneDelegate для поддержки мульти-окон.

Когда я изменил его на старый информационный лист и система AppDelegate, MCAdvertiserAssistant прекрасно работает даже с новым Xcode и Swift.

ps. На основе последней Xcode 11.2 Beta 2

...