🎃

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

に公開

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