मल्टीपीयर कनेक्टिविटी आम डेटा एक्सचेंज फॉर्मेट का एक विकल्प है। वाई-फाई या सेलुलर नेटवर्क के ज़रिए किसी इंटरमीडिएट ब्रोकर के ज़रिए डेटा एक्सचेंज करने के बजाय, जो आमतौर पर एक बैकएंड सर्वर होता है, मल्टीपीयर कनेक्टिविटी बिना किसी मध्यस्थ के कई नज़दीकी डिवाइस के बीच जानकारी एक्सचेंज करने की क्षमता प्रदान करती है।
आईफोन और आईपैड वाई-फाई और ब्लूटूथ तकनीक का उपयोग करते हैं, जबकि मैकबुक और एप्पल टीवी वाई-फाई और ईथरनेट पर निर्भर करते हैं।
यहाँ से, इस तकनीक के पक्ष और विपक्ष तुरंत सामने आते हैं। लाभों में विकेंद्रीकरण और, तदनुसार, बिचौलियों के बिना सूचना का आदान-प्रदान करने की क्षमता शामिल है।
नुकसान - iPhone और iPad के लिए वाई-फाई और ब्लूटूथ कवरेज तक या मैकबुक और एप्पल टीवी के लिए वाई-फाई और ईथरनेट तक ही साझाकरण सीमित है। दूसरे शब्दों में, सूचना का आदान-प्रदान डिवाइस के तत्काल आस-पास ही किया जा सकता है।
मल्टीपीयर कनेक्टिविटी का एकीकरण जटिल नहीं है और इसमें निम्नलिखित चरण शामिल हैं:
प्रोजेक्ट प्रीसेट
अन्य डिवाइस के लिए दृश्यता सेट करें
रेंज में दृश्यमान डिवाइसों के लिए स्कैन करें
डेटा विनिमय के लिए उपकरणों की एक जोड़ी बनाना
डेटा एक्सचेंज
आइये उपरोक्त प्रत्येक चरण पर करीब से नज़र डालें।
इस चरण में, परियोजना को मल्टीपीयर कनेक्टिविटी के कार्यान्वयन के लिए तैयार किया जाना चाहिए। ऐसा करने के लिए, आपको स्कैन करने में सक्षम होने के लिए उपयोगकर्ता से अतिरिक्त अनुमतियाँ प्राप्त करने की आवश्यकता है:
Info.plist
फ़ाइल में गोपनीयता - स्थानीय नेटवर्क उपयोग विवरण जोड़ें;Info.plist
निम्नलिखित पंक्तियों के साथ भी पूरक करने की आवश्यकता है:
<key>NSBonjourServices</key> <array> <string>_nearby-devices._tcp</string> <string>_nearby-devices._upd</string> </array>
यह ध्यान रखना महत्वपूर्ण है कि इस संदर्भ में nearby-devices
सबस्ट्रिंग का उपयोग एक उदाहरण के रूप में किया जाता है। आपके प्रोजेक्ट में, इस कुंजी को निम्नलिखित आवश्यकताओं को पूरा करना होगा:
1-15 अक्षर लंबे और वैध अक्षरों में ASCII लोअरकेस अक्षर, संख्याएं और हाइफ़न शामिल हैं, जिसमें कम से कम एक अक्षर हो और कोई आसन्न हाइफ़न न हो।
आप आवश्यकताओं के बारे में अधिक जानकारी यहां पढ़ सकते हैं।
संचार प्रोटोकॉल के लिए, उदाहरण में tcp
और upd
(अधिक विश्वसनीय और कम विश्वसनीय) का उपयोग किया गया है। यदि आपको नहीं पता कि आपको किस प्रोटोकॉल की आवश्यकता है, तो आपको दोनों दर्ज करने चाहिए।
मल्टी-पीयर कनेक्शन के लिए डिवाइस विज़िबिलिटी का संगठन MCNearbyServiceAdvertiser
द्वारा कार्यान्वित किया जाता है। आइए एक ऐसा वर्ग बनाएं जो डिवाइस के बीच जानकारी का पता लगाने, प्रदर्शित करने और साझा करने के लिए ज़िम्मेदार होगा।
import MultipeerConnectivity import SwiftUI class DeviceFinderViewModel: ObservableObject { private let advertiser: MCNearbyServiceAdvertiser private let session: MCSession private let serviceType = "nearby-devices" @Published var isAdvertised: Bool = false { didSet { isAdvertised ? advertiser.startAdvertisingPeer() : advertiser.stopAdvertisingPeer() } } init() { let peer = MCPeerID(displayName: UIDevice.current.name) session = MCSession(peer: peer) advertiser = MCNearbyServiceAdvertiser( peer: peer, discoveryInfo: nil, serviceType: serviceType ) } }
मल्टीपीयर का मूल MCSession
है, जो आपको डिवाइसों के बीच कनेक्ट करने और डेटा का आदान-प्रदान करने की अनुमति देगा।
serviceType
ऊपर उल्लिखित कुंजी है, जिसे एक्सचेंज प्रोटोकॉल के साथ Info.plist
फ़ाइल में जोड़ा गया था।
isAdvertised
प्रॉपर्टी आपको Toggle
उपयोग करके डिवाइस की दृश्यता स्विच करने की अनुमति देगी।
मल्टी-पीयर कनेक्शन के लिए डिवाइस दृश्यता स्कैनिंग MCNearbyServiceBrowser
द्वारा की जाती है:
class DeviceFinderViewModel: NSObject, ObservableObject { ... private let browser: MCNearbyServiceBrowser ... @Published var peers: [PeerDevice] = [] ... override init() { ... browser = MCNearbyServiceBrowser(peer: peer, serviceType: serviceType) super.init() browser.delegate = self } func startBrowsing() { browser.startBrowsingForPeers() } func finishBrowsing() { browser.stopBrowsingForPeers() } } extension DeviceFinderViewModel: MCNearbyServiceBrowserDelegate { func browser(_ browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) { peers.append(PeerDevice(peerId: peerID)) } func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) { peers.removeAll(where: { $0.peerId == peerID }) } } struct PeerDevice: Identifiable, Hashable { let id = UUID() let peerId: MCPeerID }
सभी दृश्यमान डिवाइसों की सूची peers
में संग्रहीत की जाएगी। MCNearbyServiceBrowser
प्रतिनिधि विधियाँ किसी पीयर के मिलने या खो जाने पर MCPeerID
जोड़ेंगी या हटाएँगी।
startBrowsing
और finishBrowsing
विधियों का उपयोग स्क्रीन दिखाई देने पर दृश्यमान डिवाइसों की खोज शुरू करने के लिए किया जाएगा, या स्क्रीन के गायब हो जाने के बाद खोज बंद करने के लिए किया जाएगा।
निम्नलिखित View
UI के रूप में उपयोग किया जाएगा:
struct ContentView: View { @StateObject var model = DeviceFinderViewModel() var body: some View { NavigationStack { List(model.peers) { peer in HStack { Image(systemName: "iphone.gen1") .imageScale(.large) .foregroundColor(.accentColor) Text(peer.peerId.displayName) .frame(maxWidth: .infinity, alignment: .leading) } .padding(.vertical, 5) } .onAppear { model.startBrowsing() } .onDisappear { model.finishBrowsing() } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Toggle("Press to be discoverable", isOn: $model.isAdvertised) .toggleStyle(.switch) } } } } }
डिवाइस दृश्यता Toggle
द्वारा सक्षम/अक्षम की जाएगी.
परिणामस्वरूप, इस स्तर पर, उपकरणों का पता लगाना और प्रदर्शित करना सही ढंग से काम करना चाहिए।
प्रतिनिधि विधि MCNearbyServiceAdvertiserdidReceiveInvitationFromPeer
डिवाइस की एक जोड़ी के बीच आमंत्रण भेजने के लिए जिम्मेदार है। उन दोनों को इस अनुरोध को संभालने में सक्षम होना चाहिए।
class DeviceFinderViewModel: NSObject, ObservableObject { ... @Published var permissionRequest: PermitionRequest? @Published var selectedPeer: PeerDevice? { didSet { connect() } } ... @Published var joinedPeer: [PeerDevice] = [] override init() { ... advertiser.delegate = self } func startBrowsing() { browser.startBrowsingForPeers() } func finishBrowsing() { browser.stopBrowsingForPeers() } func show(peerId: MCPeerID) { guard let first = peers.first(where: { $0.peerId == peerId }) else { return } joinedPeer.append(first) } private func connect() { guard let selectedPeer else { return } if session.connectedPeers.contains(selectedPeer.peerId) { joinedPeer.append(selectedPeer) } else { browser.invitePeer(selectedPeer.peerId, to: session, withContext: nil, timeout: 60) } } } extension DeviceFinderViewModel: MCNearbyServiceAdvertiserDelegate { func advertiser( _ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void ) { permissionRequest = PermitionRequest( peerId: peerID, onRequest: { [weak self] permission in invitationHandler(permission, permission ? self?.session : nil) } ) } } struct PermitionRequest: Identifiable { let id = UUID() let peerId: MCPeerID let onRequest: (Bool) -> Void }
जब selectedPeer
सेट किया जाता है, तो कनेक्ट विधि सक्रिय हो जाती है। यदि यह peer
मौजूदा peers
की सूची में है, तो इसे joinedPeer
सरणी में जोड़ दिया जाएगा। भविष्य में, इस प्रॉपर्टी को UI द्वारा संसाधित किया जाएगा।
सत्र में इस साथी की अनुपस्थिति में, browser
इस डिवाइस को जोड़ी बनाने के लिए आमंत्रित करेगा।
उसके बाद, आमंत्रित डिवाइस के लिए didReceiveInvitationFromPeer
विधि संसाधित की जाएगी। हमारे मामले में, didReceiveInvitationFromPeer
की शुरुआत के बाद, विलंबित कॉलबैक के साथ एक permissionRequest
बनाया जाता है, जिसे आमंत्रित डिवाइस पर अलर्ट के रूप में दिखाया जाएगा:
struct ContentView: View { @StateObject var model = DeviceFinderViewModel() var body: some View { NavigationStack { ... .alert(item: $model.permissionRequest, content: { request in Alert( title: Text("Do you want to join \(request.peerId.displayName)"), primaryButton: .default(Text("Yes"), action: { request.onRequest(true) model.show(peerId: request.peerId) }), secondaryButton: .cancel(Text("No"), action: { request.onRequest(false) }) ) }) ... } } }
अनुमोदन के मामले में, didReceiveInvitationFromPeer
आमंत्रण भेजने वाले डिवाइस, अनुमति और सत्र को वापस कर देगा यदि अनुमति सफल रही।
परिणामस्वरूप, आमंत्रण को सफलतापूर्वक स्वीकार करने के बाद, एक जोड़ी बनाई जाएगी:
जोड़ी बनाने के बाद, MCSession
डेटा के आदान-प्रदान के लिए जिम्मेदार है:
import MultipeerConnectivity import Combine class DeviceFinderViewModel: NSObject, ObservableObject { ... @Published var messages: [String] = [] let messagePublisher = PassthroughSubject<String, Never>() var subscriptions = Set<AnyCancellable>() func send(string: String) { guard let data = string.data(using: .utf8) else { return } try? session.send(data, toPeers: [joinedPeer.last!.peerId], with: .reliable) messagePublisher.send(string) } override init() { ... session.delegate = self messagePublisher .receive(on: DispatchQueue.main) .sink { [weak self] in self?.messages.append($0) } .store(in: &subscriptions) } } extension DeviceFinderViewModel: MCSessionDelegate { func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) { guard let last = joinedPeer.last, last.peerId == peerID, let message = String(data: data, encoding: .utf8) else { return } messagePublisher.send(message) } }
विधि func send(_ data: Data, toPeers peerIDs: [MCPeerID], with mode: MCSessionSendDataMode) throws
साथियों के बीच डेटा भेजने में मदद करता है।
प्रतिनिधि विधि func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID)
उस डिवाइस पर ट्रिगर होती है जिसने संदेश प्राप्त किया था।
इसके अलावा, एक मध्यवर्ती प्रकाशक messagePublisher
उपयोग संदेशों को प्राप्त करने के लिए किया जाता है, क्योंकि MCSession
प्रतिनिधि विधि DispatchQueue global()
में सक्रिय होती है।
मल्टीपीयर कनेक्टिविटी एकीकरण प्रोटोटाइप पर अधिक विवरण इस में पाया जा सकता है
मुझसे संपर्क करने में संकोच न करें