简体   繁体   中英

Send String and NSData at the same time over peer to peer?

I am adding text fields which are of type (String) and an image which is of type (NSData) to a dictionary sending it to a peer, and on the other side it is decoding the dictionary in to a Strings with key value pairs.

The image data in the dictionary is no longer NSData but a string. How would I send the string and data at the same time and retrieve it as a string and data?

import MultipeerConnectivity
import UIKit


class ViewController: UIViewController, MCSessionDelegate, MCBrowserViewControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

var browser : MCBrowserViewController!
var assistant : MCAdvertiserAssistant!
var session : MCSession!
var peerID: MCPeerID!

var firstNameVar = ""
var lastNameVar = ""
var imageDataVar: NSData!

let imagePicker  = UIImagePickerController()
var tapGestureID = Int()

@IBOutlet weak var firstLame: UITextField!
@IBOutlet weak var lastName: UITextField!
@IBOutlet weak var firstNameLabel: UILabel!
@IBOutlet weak var lastNameLabel: UILabel!
@IBOutlet weak var contactImage: UIImageView!

@IBAction func showBrowser(sender: UIButton) {
    self.presentViewController(self.browser, animated: true, completion: nil)
}

@IBAction func getImage(sender: AnyObject) {
    chooseImageContact()
}

@IBAction func sendChat(sender: AnyObject) {
    sendInfo()
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.peerID = MCPeerID(displayName: UIDevice.currentDevice().name)

    //self.session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .Required)
    self.session = MCSession(peer: self.peerID)
    self.session.delegate = self

    // create the browser viewcontroller with a unique service name
    self.browser = MCBrowserViewController(serviceType: "LCOC-Chat", session: self.session)
    self.browser.delegate = self

    // tell the assistant to start advertising our fabulous chat
    self.assistant = MCAdvertiserAssistant(serviceType:"LCOC-Chat", discoveryInfo:nil, session:self.session)
    self.assistant.start()
}

func sendInfo() {
    if self.session.connectedPeers.count > 0 {
        firstNameVar = firstLame.text!
        lastNameVar = lastName.text!
        let myDictionary = ["itemA" : "\(firstNameVar)", "itemB" : "\(lastNameVar)", "itemC" : "\(imageDataVar)"]
        do {
        let data =  NSKeyedArchiver.archivedDataWithRootObject(myDictionary)
        try self.session.sendData(data, toPeers: self.session.connectedPeers, withMode: MCSessionSendDataMode.Unreliable)
        } catch let error as NSError {
                let ac = UIAlertController(title: "Send error", message: error.localizedDescription, preferredStyle: .Alert)
                    ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
                    presentViewController(ac, animated: true, completion: nil)
            }
    }
    self.firstLame.text = ""
    self.lastName.text = ""
}


// Called when a peer sends an NSData to us
func session(session: MCSession, didReceiveData data: NSData, fromPeer peerID: MCPeerID) {

     // This needs to run on the main queue
    dispatch_async(dispatch_get_main_queue()) {
    let myDictionary = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! NSDictionary
        self.firstNameLabel.text = myDictionary.valueForKey("itemA") as? String
        self.lastNameLabel.text = myDictionary.valueForKey("itemB") as? String

//            self.firstNameVar = myDictionary.valueForKey("itemA") as? String
//            self.lastNameVar = myDictionary.valueForKey("itemB") as? String
//            let image = myDictionary.valueForKey("itemC") as? String
//            let imageData = NSKeyedUnarchiver.unarchiveObjectWithData(image) as? NSData

    }
}

func browserViewControllerDidFinish(browserViewController: MCBrowserViewController) {
    dismissViewControllerAnimated(true, completion: nil)
}
func browserViewControllerWasCancelled(browserViewController: MCBrowserViewController) {
    dismissViewControllerAnimated(true, completion: nil)
}
func browserViewController(browserViewController: MCBrowserViewController, shouldPresentNearbyPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) -> Bool {
    return true
}

func session(session: MCSession, peer peerID: MCPeerID, didChangeState state: MCSessionState) {
    switch state {
    case MCSessionState.Connected:
        print("Connected: \(peerID.displayName)")
    case MCSessionState.Connecting:
        print("Connecting: \(peerID.displayName)")
    case MCSessionState.NotConnected:
        print("Not Connected: \(peerID.displayName)")
    }
}

func session(session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, withProgress progress: NSProgress) {
}
func session(session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, atURL localURL: NSURL, withError error: NSError?) {
}
func session(session: MCSession, didReceiveStream stream: NSInputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}


// Picking the image
func chooseImageContact(){
    let imagePicker        = UIImagePickerController()
    imagePicker.delegate   = self
    imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
    self.presentViewController(imagePicker, animated: true, completion: nil)
}

//Scalling the image
func scaleContactImageWith(image:UIImage, newSize:CGSize)->UIImage{
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
    image.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
    let newContactImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newContactImage
}

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    //This gets the Contact image inside the imagePickerController
        let pickedImage:UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage
        let smallPicture        = scaleContactImageWith(pickedImage, newSize: CGSizeMake(100, 100))
        var sizeOfImage:CGRect  = contactImage.frame
        sizeOfImage.size    = smallPicture.size
        contactImage.frame  = sizeOfImage
        picker.dismissViewControllerAnimated(true, completion: nil)
        contactImage.image = smallPicture

        imageDataVar = UIImagePNGRepresentation(smallPicture)!
    }

}

You are currently converting the NSData to a String using the data's description method. Never do that.

A much better solution would be to simply put the data in the dictionary as-is since you are archiving the dictionary and sending the data. No need to convert the image data into a string.

Then on the receiving end, you unarchive the received data and the dictionary already has the PNG data for the image.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM