🎃

Project 25 of 100 Days of Swift in iOS15 学習記録

2022/07/25に公開

100 Days of Swiftを勉強しているうちに
自分が出会った問題と解決方法を記録します

環境

Xcode 13.3.1
iPhone SE3 iOS 15.4

CellViewのCellが大きすぎる

まずはCollection Viewをセレクト

Size Inspectorをクリック
Estimate Sizeに「None」を選択
(元々はAutomaticでした)

再びビルドします、これでOKです

実機ではエラーが出ます

実機で操作してみるとこういうエラーが出ました

2022-07-26 00:03:46.678499+0800 SelfieShare[89221:11164923] [MCNearbyServiceBrowser] NSNetServiceBrowser did not search with error dict [{
    NSNetServicesErrorCode = "-72008";
    NSNetServicesErrorDomain = 10;
}].

解決法はInfo.plistに2つの情報を入れることです

一つ目:Privacy - Local Network Usage Description
記入例は:We need to access local network.

二つ目は:Bonjour services
配列なので、記入例は二つのアイテムがあります:_hws-project25._tcpと_hws-project25._udpです

これで完了となりました

Decline/AcceptのAlertがずっと出ない

シミュレーターAがHost Sessiontをクリックして、
シミュレーターBがJoin Sessionをクリック、そしてデバイスをセレクトのシートが出て、そこでシミュレーターAの名前を選択します

この時点で、シミュレーターAが上図のようなDecline/AcceptのAlertが出るはずなのに、ずっと出ませんでした

その原因は、サンプルコードが使用されているMCAdvertiserAssistantは、iOS 13から仕様になったSceneDelegateとは不具合が出るらしいです

解決法はMCAdvertiserAssistantの代わりにMCNearbyServiceAdvertiserを使います
MCAdvertiserAssistantはAlertのカスタムはできませんが、MCNearbyServiceAdvertiserはAlertカスタムできます

まずは定義と型を変更します

viewController.swift
class ViewController: UICollectionViewController, ...省略... {

	...省略...
-	var mcAdvertiserAssistant: MCAdvertiserAssistant?
+	var mcNearbyServiceAdvertiser: MCNearbyServiceAdvertiser?

そして、MCNearbyServiceAdvertiserDelegateというプロトコルを追加します

viewController.swift
-class ViewController: UICollectionViewController, ...省略... {
+class ViewController: UICollectionViewController, ...省略..., MCNearbyServiceAdvertiserDelegate {

MCNearbyServiceAdvertiserDelegateが追加されたので、対応したfunctionを追加します
こちらはAlertの内容をカスタムしています

viewController.swift
class ViewController: UICollectionViewController, ...省略... {
	...省略...
	
+	func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
+		invitationHandler(true, mcSession)
+
+		let ac = UIAlertController(title: "Connection Request", message: "User: \(peerID.displayName) is requesting to join the network.", preferredStyle: .alert)
+		ac.addAction(UIAlertAction(title: "Allow", style: .default) {[weak self] action in
+			invitationHandler(true, self?.mcSession)
+		})
+		ac.addAction(UIAlertAction(title: "Deny", style: .cancel) {[weak self] action in
+			invitationHandler(false, self?.mcSession)
+		})
+		present(ac, animated: true)
+	}

そして、サンプルコードのstartHostingを改正します

viewController.swift
class ViewController: UICollectionViewController, ...省略... {
	...省略...
	
	func startHosting(action: UIAlertAction) {
-		guard let mcSession = mcSession else { return }
-		mcAdvertiserAssistant = MCAdvertiserAssistant(serviceType: "hws-project25", discoveryInfo: nil, session: mcSession)
-		mcAdvertiserAssistant?.start()
+		mcNearbyServiceAdvertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "hws-project25")
+		mcNearbyServiceAdvertiser?.delegate = self
+		mcNearbyServiceAdvertiser?.startAdvertisingPeer()
	}

最後はビルドしてみます
Alertが無事に出ました

Discussion