2015-12-28 23 views
4

我使用IOS聯繫人框架檢索iPhone用戶的聯繫人的的imageData發送。如果imageData是可用的,我檢索它並需要編碼它成一個字符串。這是因爲我正在使用Multipeer連接框架,我想在瀏覽的對等列表中顯示對等人顯示名稱旁邊的圖像。我正在發送編碼的imageDataMCNearbyServiceAdvertiser類的初始化後的discoveryInfo字典參數。IOS聯繫人框架,如何編碼和解碼的imageData轉換成String,並通過infoDiscovery字典,MPC廣告

要做到這一點,我嘗試使用UTF8的Base64編碼的imageData,但都失敗了。

這是我試過的UTF8編碼過程的代碼:

// Retrieve user image and initials from global userContact variable 

func retrieveUserImageAndInitials() -> Dictionary<String,String> { 
    let userFirstNameInitial = "\(userContact.firstName[userContact.firstName.startIndex])" 
    let userLastNameInitial = "\(userContact.lastName[userContact.lastName.startIndex])" 

    if userContact.imageData != nil { 
     print("Image data found") 

     if let dataString = NSString(data: userContact.imageData!, encoding: NSUTF8StringEncoding) as String! { 
      print("Image data encoded successfully") 
      return ["firstNameInitial":userFirstNameInitial, "lastNameInitial":userLastNameInitial,"imageData":dataString] 
     } 
     else { 
      print("Image data encoded with failures") 
      return ["firstNameInitial":userFirstNameInitial, "lastNameInitial":userLastNameInitial] 
     } 
    } 
    else { 
     print("Image data not found") 
     return ["firstNameInitial":userFirstNameInitial, "lastNameInitial":userLastNameInitial] 
    } 
} 

這是使用UTF8解碼代碼:

func browser(browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) { 
    foundPeers.append(peerID) 

    let userInitials = info!["firstNameInitial"]! + info!["lastNameInitial"]! 

    if let dataString = info!["imageData"] { 
     print("Data string found") 

     if let imageData = dataString.dataUsingEncoding(NSUTF8StringEncoding) { 
      print("Image data fetched succesfully!") 
      imagesOfFoundPeers.append(UIImage(data: imageData)!) 
     } 
     else { 
      print("Image data not fetched") 
      imagesOfFoundPeers.append(imageFromText(userInitials, 
       font: UIFont(name: "Pacifico", size: 24.0)!, maxWidth: 50.0, color: UIColor.mainColor())) 
     } 
    } 
    else { 
     print("Data string not found") 
     print("Image with initials used instead") 
     imagesOfFoundPeers.append(imageFromText(userInitials, 
      font: UIFont(name: "Pacifico", size: 24.0)!, maxWidth: 50.0, color: UIColor.mainColor())) 
    } 

    delegate?.foundPeer() 
} 

在使用UTF8編碼,我從編碼過程獲得的字符串打印爲零,所以代碼甚至從來沒有發送通過廣告客戶

這是我試過的的Base64編碼過程中的代碼:

// Retrieve user image and initials from global userContact variable 
func retrieveUserImageAndInitials() -> Dictionary<String,String> { 
    let userFirstNameInitial = "\(userContact.firstName[userContact.firstName.startIndex])" 
    let userLastNameInitial = "\(userContact.lastName[userContact.lastName.startIndex])" 

    if userContact.imageData != nil { 
     print("Image data found") 

     let dataString = userContact.imageData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength) 

     print("Image data encoded successfully") 
     return ["firstNameInitial":userFirstNameInitial, "lastNameInitial":userLastNameInitial,"imageData":dataString] 

    } 
    else { 
     print("Image data not found") 
     return ["firstNameInitial":userFirstNameInitial, "lastNameInitial":userLastNameInitial] 
    } 
} 

這是使用的Base64 解碼代碼:

func browser(browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) 
{ 
    foundPeers.append(peerID) 

    let userInitials = info!["firstNameInitial"]! + info!["lastNameInitial"]! 

    if let dataString = info!["imageData"] { 
     print("Data string found") 

     let imageData = NSData(base64EncodedString: dataString, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) 
     let userImage = UIImage(data: imageData!) 
     print("Image data fetched succesfully!") 
     imagesOfFoundPeers.append(userImage!) 

    } 
    else { 
     print("Data string not found") 
     print("Image with initials used instead") 
     imagesOfFoundPeers.append(imageFromText(userInitials, 
      font: UIFont(name: "Pacifico", size: 24.0)!, maxWidth: 50.0, color: UIColor.mainColor())) 
    } 

    delegate?.foundPeer() 
} 

在使用的Base64編碼,代碼確實將數據編碼成字符串,但應用程序終止,因爲字典di包含由編碼過程產生的字符串的scoveryInfo被認爲是MCNearbyServiceAdvertiser的無效參數。

它拋出以下消息:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid discoveryInfo passed to MCNearbyServiceAdvertiser'

這是MCNearbyServiceAdvertiser的初始化和所有MPCManagement對象:

override init() 
{ 
    super.init() 

    userContact = retrieveUserContact() 

    peer = MCPeerID(displayName: userContact.fullName) 

    dataSession = MCSession(peer: peer) 
    dataSession.delegate = self 

    deviceBrowser = MCNearbyServiceBrowser(peer: peer, serviceType: "dummy-mpc") 
    deviceBrowser.delegate = self 

    deviceAdvertiser = MCNearbyServiceAdvertiser(peer: peer, discoveryInfo: retrieveUserImageAndInitials(), serviceType: "dummy-mpc") 
    deviceAdvertiser.delegate = self 
} 

難道我做錯了什麼,還是什麼其他選項我有編碼和發送imageData?

在此先感謝!

+0

嘗試base64EncodedStringWithOptions(NSDataBase64EncodingOptions()) –

+0

不要在發現信息中發送該類數據。建立連接,然後將數據發送到您的同位 – ChrisH

+0

@ChrisH我知道,從base64編碼生成的字符串對於discoveryInfo字典來說太長了,但我希望能夠事先顯示圖像。這有點像應用程序的魔力:P我可以嘗試一下,正如Jasper Bryant-Greene所說的那樣,用Bonjour創建一個定製的發現課程,但是我在這個主題上有點綠色。 –

回答

1

一般來說,Base64應該是正確的方法,因爲它可以編碼任意二進制數據。您的代碼是正確的,但我不會在解碼器中使用IgnoreUnknownCharacters選項,因爲沒有理由會引入意外字符,因此此設置可能會隱藏您的錯誤。 UTF-8永遠不會工作,因爲它不是任意二進制數據的編碼方案。

您的代碼失敗,因爲discoveryInfo字典對鍵值對的大小有限制。

documentation of MCNearbyServiceAdvertiser

信息

被提供給瀏覽器的鍵值對的字典。 每個鍵和值都必須是NSString對象。

該數據使用Bonjour TXT記錄進行廣告,該記錄按 至RFC 6763(第6部分)編碼。其結果是:

  • 的鍵 - 值對必須大於當 以UTF-8格式編碼具有等於所述鍵和 的值之間等號(=)255個字節(總)不再。
  • 鍵不能包含等號。

你可以變通的作法是嚴重降低了圖像的分辨率,但由此產生的圖像將可能是面目全​​非。您還可以將圖像分割爲多個字典密鑰,但由於您試圖通過DNS TXT記錄傳輸的數據量很可能會導致發現性能很差。

您可能需要考慮在之後傳輸圖像數據您已設置對等連接,而不是作爲發現的一部分。另外,您也可以在卓悅之上構建自己的發現機制,如文檔中建議:

如果您需要提供的數據太大,以適應這些 限制之內,你應該創建一個自定義的發現類使用Bonjour的 發現和您選擇的網絡協議來交換 信息。

+0

好吧,所以我唯一可以接受的選擇是在Bonjour之上建立自己的發現機制。事情是,Bonjour我有點綠。你能推薦一些我可以用來學習和製作這種機制的材料嗎? –

相關問題