Pull to Refresh in Swift not Reloading UITableView - ios

I've got JSON filling my UITableView successfully, but the JSON is often updated so I need the ability to refresh. I followed THIS TUTORIAL to implement a pull to refresh control. Visually, it seems like it all works correctly, but when I call tableView.reloadData() the table doesn't reload. However, if I leave the ViewController and return, the table is updated. Why would tableView.reloadData() work in viewDidAppear and viewWillAppear but not in my custom refresh() function?
MainVC.swift file
class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableView: UITableView!
var dataArray: NSArray = NSArray()
#IBOutlet var Controller: UISegmentedControl!
var refreshControl:UIRefreshControl!
func refresh(sender:AnyObject)
{
refreshBegin("Refresh",
refreshEnd: {(x:Int) -> () in
self.tableView .reloadData()
println("Table Reloaded")
self.refreshControl.endRefreshing()
})
}
func refreshBegin(newtext:String, refreshEnd:(Int) -> ()) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
println("refreshing")
sleep(2)
dispatch_async(dispatch_get_main_queue()) {
refreshEnd(0)
}
}
}
override func viewWillAppear(animated: Bool) {
self.tableView .reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.titleView = UIImageView(image: UIImage(named: "logojpg.jpg"))
startConnectionAt("http://www.domain.com/json.php")
refreshControl = UIRefreshControl()
refreshControl.backgroundColor = UIColor.orangeColor()
refreshControl.tintColor = UIColor.whiteColor()
refreshControl.attributedTitle = NSAttributedString(string: "Pull to Refresh")
refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
tableView.addSubview(refreshControl)
}
//MARK: JSON Loading
var data: NSMutableData = NSMutableData()
func startConnectionAt(urlPath: String){
var url: NSURL = NSURL(string: urlPath)
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
connection.start()
}
func connection(connection: NSURLConnection!, didFailWithError error: NSError!) {
println("Connection failed.\(error.localizedDescription)")
}
func connection(connection: NSURLConnection, didRecieveResponse response: NSURLResponse) {
println("Recieved response")
}
func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
self.data = NSMutableData()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
self.data.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
var dataAsString: NSString = NSString(data: self.data, encoding: NSUTF8StringEncoding)
var err: NSError
var json: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var results: NSArray = json["needs"] as NSArray
self.dataArray = results
tableView.reloadData()
println("success")
}
//End loading of JSON
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.dataArray.count;
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell:CustomCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as CustomCell
var rowData: NSDictionary = dataArray[indexPath.row] as NSDictionary
var firstName=rowData["needFirstname"] as String
var descrip=rowData["needDescription"] as String
var poster=rowData["needPoster"] as String
var city=rowData["needCity"] as String
var state=rowData["needState"] as String
var country=rowData["needCountry"] as String
cell.needFirstName.text = firstName
cell.needDescription.text = descrip
cell.needDescription.numberOfLines = 0
cell.needPoster.text = poster
cell.needCity.text = city
cell.needState.text = state
cell.needCountry.text = country
return cell
}
#IBAction func Change(sender: AnyObject) {
if Controller.selectedSegmentIndex == 0 {
startConnectionAt("http://www.domain.com/localJSON.php")
}
else if Controller.selectedSegmentIndex == 1 {
startConnectionAt("http://www.domain.com/intlJSON.php")
}
self.tableView .reloadData()
}
}

Your last comment is right-on in my view.
During your pull to refresh function, you call tableView.reloadData(), however, reloadData() does not inherently do any repopulating the elements in the data source (in your case, dataArray). It simply reloads all the data that's currently in the table view's data source at the time it is called.
So my recommendation would be to construct your refresh function such that the following happens:
Initiate a request to your web service.
When the response comes back (ie, connectionDidFinishLoading is executed), parse the JSON results and assign that result to the dataArray instance. You seem to be doing this already in connectionDidFinishLoading, so it's just a matter of sending the request to your web service, I'd think.
Call tableView.reloadData() to display any new elements that have been added since the last time the tableView's data was displayed. Again, you're doing this already in connectionDidFinishLoading, so #1 is the primary thing that I think needs to happen.

Referring to https://stackoverflow.com/a/25957339
Not sure but maybe the connection is run on a different thread, if so you need to run the table update on the main UI thread
// using Swift's trailing closure syntax:
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}

Related

ios Swift Protocol Data

I don't use storyboards.
I want to send protocol data using #objc button action.
However, the sent view controller does not run the protocol function.
May I know what the reason is?
In fact, there's a lot more code.
Others work, but only protocol functions are not executed.
The didUpdataChampion function is
Data imported into a different protocol.
I have confirmed that there is no problem with this.
protocol MyProtocolData {
func protocolData(dataSent: String)
func protocolCount(dataInt: Int)
}
class PickViewController: UIViewController,ChampionManagerDelegate{
static let identifier = "PickViewController"
var count = 0
var urlArray = [URL]()
var pickDelegate : MyProtocolData?
override func viewDidLoad() {
super.viewDidLoad()
champions.riot(url: "myURL")
}
#objc func topHand(){
pickDelegate?.protocolData(dataSent: "top")
print(count)
pickDelegate?.protocoCount(dataInt: count)
let cham = ChampViewController()
cham.modalPresentationStyle = .fullScreen
present(cham, animated: true, completion: nil)
}
//Data imported to another protocol
func didUpdataChampion(_ championManager: ChampionManager, champion: [ChampionRiot]) {
print(#function)
count = champion.count
for data in champion {
let id = data.id
guard let url = URL(string: "https://ddragon.leagueoflegends.com/cdn/11.16.1/img/champion/\(id).png") else { return }
urlArray.append(url)
count = urlArray.count
}
}
func didFailWithError(error: Error) {
print(error)
}
}
class ChampViewController: UIViewController,MyProtocolData {
var pickData = ""
var arrayCount = 0
override func viewDidLoad() {
super.viewDidLoad()
}
func protocolData(dataSent: String) {
print(#function)
pickData = dataSent
print(pickData)
}
func protocoCount(dataInt: Int) {
print(#function)
arrayCount = dataInt
print(arrayCount)
}
}
i don't see full code, for instance how you call bind to topHand(), my advice is:
check that topHand - is called
check that pickDelegate isn't nil inside topHand
Create Object fo your PickViewController class and set its delegate to self.
var yourObj = PickViewController()
override func viewDidLoad() {
super.viewDidLoad()
yourObj.delegate = self
}

How to print data in empty array

I'm trying to print the chat array that is declared as a empty global variable in a table. The data that I'm trying to print is received using web sockets. I'm assigning the data in the messageReceived function, and I know that the data is getting to the program because I'm printing in a label, but the moment that I'm trying to print it in the table is simple not working. All of this is in the ViewController.swift:
import UIKit
import Starscream
var messagetext: String = ""
var tabletext: String = ""
var chat = [String] ()
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
var socket = WebSocket(url: URL(string: "ws://localhost:1337/")!, protocols: ["chat"])
#IBOutlet weak var chatMessage: UILabel!
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var tableView: UITableView!
#IBAction func buttonClick(_ sender: Any) {
messagetext = textField.text!
sendMessage(messagetext)
}
override func viewDidLoad() {
super.viewDidLoad()
self.textField.delegate = self
socket.delegate = self
socket.connect()
navigationItem.hidesBackButton = true
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
func textFieldDidEndEditing(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return (true)
}
deinit{
socket.disconnect(forceTimeout: 0)
socket.delegate = nil
}
}
// MARK: - FilePrivate
fileprivate extension ViewController {
func sendMessage(_ messager: String) {
socket.write(string: messager)
}
func messageReceived(_ message: String) {
chatMessage.text = message
chat.append(message)
}
}
// MARK: - WebSocketDelegate
extension ViewController : WebSocketDelegate {
public func websocketDidConnect(_ socket: Starscream.WebSocket) {
}
public func websocketDidDisconnect(_ socket: Starscream.WebSocket, error: NSError?) {
performSegue(withIdentifier: "websocketDisconnected", sender: self)
}
public func websocketDidReceiveMessage(_ socket: Starscream.WebSocket, text: String) {
// 1
guard let data = text.data(using: .utf16),
let jsonData = try? JSONSerialization.jsonObject(with: data),
let jsonDict = jsonData as? [String: Any],
let messageType = jsonDict["type"] as? String else {
return
}
// 2
if messageType == "message",
let messageData = jsonDict["data"] as? [String: Any],
let messageText = messageData["text"] as? String {
messageReceived(messageText)
}
}
public func websocketDidReceiveData(_ socket: Starscream.WebSocket, data: Data) {
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return(chat.count)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
cell.textLabel?.text = chat[indexPath.row] as! String
return(cell)
}
}
Assuming that you are sure about there is data to be received by your view controller, The issue would be: the tableview data source methods are called before receiving any data, which means chat data source array is still empty, thus there is no data to display.
The solution for your case is to make sure to reload the tableview after receiving data (updating the value of chat data source array), which means in your case after appending a message to chat in messageReceived method by calling reloadData() UITableView instance method:
func messageReceived(_ message: String) {
chatMessage.text = message
chat.append(message)
// here we go:
tableView.reloadData()
}
In your message received handler, issue a tableview.reloadData()
Cheers!
You need to tell the tableview that there is new data. You also need to allow for the fact that the network operation probably occurred on a background queue and UI updates must be on the main queue:
func messageReceived(_ message: String) {
DispatchQueue.main.async {
let newRow = IndexPath(row: chat.count, section:0)
chatMessage.text = message
chat.append(message)
tableView.insertRows(at:[newRow],with: .automatic)
}
}

Code that otherwise runs well is crashing application when used in viewDidLoad()

I am working on an application that retrieves a user's friends from a database and outputs then in a table view.
I have successfully coded the table view to the point where it reads the indexes I insert into an NSMutableArray(). My thinking is to use NSURL to send a query to a MySQL database via URL variables with PHP.
I have used NSURL many times to interact with the database, however when I use it in the viewDidLoad() function to load the friends immediately on the application's load, it crashes but does not return an error.
Code:
class viewFriendsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var textArray: NSMutableArray = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
let myUrl = NSURL(string: "http://www.casacorazon.org/ios.html")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
if error != nil {
print("Error: \(error)")
}
dispatch_async(dispatch_get_main_queue()) {
print(responseString)
}
}
}
task.resume()
//get username from NSUserDefaults
//if username inavailable, insert error report into first row
//use PHP script to get friends from user's database
//split return string by '9245203598' into array
//load split array into NSMutableArray via foreach loop
//let username = NSUserDefaults.standardUserDefaults().stringForKey("username")*/
self.textArray.addObject("First Index")
self.textArray.addObject("Second Index")
self.textArray.addObject("Third Index")
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 44.0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.textArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
cell.textLabel?.text = self.textArray.objectAtIndex(indexPath.row) as? String
return cell
}
func sendAlert(subject: String, message: String) {
let alertController = UIAlertController(title: subject, message:
message, preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
}
because your app complete excuting the code in UI before the background finish its task. you have to ensure that background task is completed then continue in UI.
Note: NSUrlsesstion is running in background you don't have to import dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {} inside it.

Swift Pull to Refresh doesn't Show

i've add Pull To Refresh on UITableView on my Swift project successful, on another ViewController i'm not able to show it.
On the others view the code is the same without LocationManager functions.
I don't know where is my error!
Below my code:
import UIKit
import CoreLocation
class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
var locationCoordinates: CLLocationCoordinate2D!
#IBOutlet weak var bannerView: GADBannerView!
var dati = NSMutableArray()
var datiComplete = NSDictionary()
#IBOutlet weak var tableView: UITableView!
var arrayOfData: [MyData] = [MyData]()
var url:NSURL!
var refreshControl = UIRefreshControl()
var dateFormatter = NSDateFormatter()
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager = CLLocationManager()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest //Battery drain!
self.locationManager.distanceFilter = 1
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
searchUser()
self.dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
self.dateFormatter.timeStyle = NSDateFormatterStyle.LongStyle
self.refreshControl = UIRefreshControl()
self.refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
self.refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
self.tableView.insertSubview(refreshControl, atIndex: 0)
self.handleRefresh()
}
func refresh(sender:AnyObject)
{
println("Refresh work!")
self.handleRefresh()
}
func handleRefresh() {
if locationManager.location != nil {
url = NSURL(string: "http://www.myURL.com/data.php?lat=\(locationManager.location.coordinate.latitude)&lon=\(locationManager.location.coordinate.longitude)&max=15&when=now")!
} else {
url = NSURL(string: "http://www.myURL.com/data.php?lat=41&lon=11&max=10&when=now")!
}
//println("Call URL!!")
var request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Accept")
var reponseError: NSError?
var response: NSURLResponse?
//var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {
response, data, error in
if (error != nil) {
return
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
var error: NSError?
self.dati = (NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &error) as! NSDictionary)["spots"] as! NSMutableArray
if (error != nil){
return
}
// **** Json Parsing *****
dispatch_async(dispatch_get_main_queue()){
self.tableView.reloadData()
self.tableView.delegate = self
self.tableView.dataSource = self
}
}
})
let now = NSDate()
let updateString = "Last Updated at " + self.dateFormatter.stringFromDate(now)
self.refreshControl.attributedTitle = NSAttributedString(string: updateString)
if self.refreshControl.refreshing
{
self.refreshControl.endRefreshing()
}
self.tableView?.reloadData()
refreshControl.endRefreshing()
}
func searchUser(){
println("Start Search User")
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestAlwaysAuthorization()
self.locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!){
println("Start Location Manager Func")
self.locationCoordinates = manager.location.coordinate
self.locationManager.stopUpdatingLocation()
println("**************** locations = \(self.locationCoordinates.latitude) \(self.locationCoordinates.longitude)")
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.setNavigationBarItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayOfData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: ViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as! ViewCell
cell.backgroundColor = UIColor.whiteColor()
let usr = arrayOfData[indexPath.row]
cell.setCell(<Cell-data>)
return cell
}
var selectedSpot:String? = nil
var selectedSpotIndex:Int? = nil
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "GoSpotDetails" {
var tabBarC : TabBarController = segue.destinationViewController as! TabBarController
var caseIndex = tableView!.indexPathForSelectedRow()!.row
var selectedCase = self.arrayOfSpotsTemp[caseIndex]
tabBarC.DataDetail = selectedCase
}
}
}
Thanks a lot.
Well, your code needs lot of changes. Let me give you some suggestions.
Instead of self.tableView.insertSubview(refreshControl, atIndex: 0) try to use tableView.addSubview(refreshControl). Look thedifference between add and insert subview here
Define another function to populate view. Eg. func populateView()
Replace self.handleRefresh() with self.populateView()
Replace
self.refreshControl.addTarget(
self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged
)
with
self.refreshControl.addTarget(
self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged
)
In func handleRefresh() initiate the refreshing by using refreshControl.beginRefreshing() then remove all the objects, reload the tableView, end refreshing and populate the view.
EDIT
I have misunderstood your question.
Why its not working in other view?
Its because in UITableViewController refreshControl comes pre-fit, a regular ViewController does not.
So what to do?
Here is a snippet defining a lazily instantiated variable which creates and configures a UIRefreshControl:
lazy var refreshControl: UIRefreshControl = {
let refreshControl = UIRefreshControl()
refreshControl.addTarget(
self, action: "handleRefresh", forControlEvents: .ValueChanged
)
return refreshControl
}()
In viewDidLoad() add UIRefreshControl as a subview to the tableView as:
self.tableView.addSubview(self.refreshControl)
Hope this helps you to understand!

Can't get an array from another view controller Swift

I'm making an Orientation (don't know if it's the right name in english) app. You can scan a Qr code and then you can send the results to your teacher. I'm using Multipeer connection to send the results from the students phone and the teachers. I have one UITableViewController and I want to make an array (with a struct, 2 values) available for another view controller -> UIViewController. And there's the problem. When I try to "send" it to the other viewControler it doesn't reach to the end ore something. I have tried everything (controlsGetShared is one try) I can, but still it doesn't work... :(
The Struct looks like this
struct Control {
let name: String
let code: String
}
The UITableViewController looks like
import UIKit
class ControlViewController: UITableViewController {
var controlsGet = [Control] ()
var controlsGetShare = [Control] ()
var def = NSUserDefaults.standardUserDefaults()
var valueName: String = ""
var valueCode: String = ""
#IBAction func done(segue: UIStoryboardSegue) {
var scanVc = segue.sourceViewController as ScanViewController
valueName = scanVc.name
valueCode = scanVc.code
println("sendToSendFile \(valueName) \(valueCode)")
controlsGet.append(Control(name: valueName, code: valueCode))
//controlsGetShare.append(Control(name: valueName, code: valueCode))
println("\(self.controlsGet.count) shareArray \(self.controlsGetShare.count)")
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
controlsGetShare = controlsGet
println("preparaForSegueCount \(controlsGetShare.count)")
}
override func viewDidLoad() {
println("viewDidLoad")
tableView.reloadData()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.controlsGet.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
//for index in controlsGet {
var control : Control
control = controlsGet[indexPath.row]
cell.textLabel.text = control.name
cell.detailTextLabel?.text = control.code
//}
return cell
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
controlsGet.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
}
Ant the send UIViewControler
import UIKit
import MultipeerConnectivity
class SendFileViewController: UIViewController, MCBrowserViewControllerDelegate,
MCSessionDelegate {
let serviceType = "LCOC-Chat"
var controlsGetShare = [Control] ()
#IBAction func done(segue: UIStoryboardSegue) {
var controlVc = segue.sourceViewController as ControlViewController
println(controlVc.controlsGetShare.count)
controlsGetShare = controlVc.controlsGetShare
println(controlsGetShare.count)
}
var browser : MCBrowserViewController!
var assistant : MCAdvertiserAssistant!
var session : MCSession!
var peerID: MCPeerID!
#IBOutlet var chatView: UITextView!
#IBOutlet var messageField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.peerID = MCPeerID(displayName: UIDevice.currentDevice().name)
self.session = MCSession(peer: peerID)
self.session.delegate = self
// create the browser viewcontroller with a unique service name
self.browser = MCBrowserViewController(serviceType:serviceType,
session:self.session)
self.browser.delegate = self;
self.assistant = MCAdvertiserAssistant(serviceType:serviceType,
discoveryInfo:nil, session:self.session)
// tell the assistant to start advertising our fabulous chat
self.assistant.start()
}
#IBAction func sendChat(sender: UIButton) {
println("sendButton")
// Bundle up the text in the message field, and send it off to all
// connected peers
var error : NSError?
var message = ""
/*
var msg = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
self.session.sendData(msg, toPeers: self.session.connectedPeers, withMode: MCSessionSendDataMode.Unreliable, error: &error)
*/
println(self.controlsGetShare.count)/*
for index in controlsGetShare {
message = index.name
var msg = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
self.session.sendData(msg, toPeers: self.session.connectedPeers, withMode: MCSessionSendDataMode.Unreliable, error: &error)
if error != nil {
print("Error sending nameData: \(error?.localizedDescription)")
}
println("didSendDataA")
message = index.code
msg = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
self.session.sendData(msg, toPeers: self.session.connectedPeers, withMode: MCSessionSendDataMode.Unreliable, error: &error)
if error != nil {
print("Error sending codeData: \(error?.localizedDescription)")
}
println("didSendDataB")
}*/
}
#IBAction func showBrowser(sender: UIButton) {
// Show the browser view controller
self.presentViewController(self.browser, animated: true, completion: nil)
}
func browserViewControllerDidFinish(
browserViewController: MCBrowserViewController!) {
// Called when the browser view controller is dismissed (ie the Done
// button was tapped)
self.dismissViewControllerAnimated(true, completion: nil)
}
func browserViewControllerWasCancelled(
browserViewController: MCBrowserViewController!) {
// Called when the browser view controller is cancelled
self.dismissViewControllerAnimated(true, completion: nil)
}
func session(session: MCSession!, didReceiveData data: NSData!,
fromPeer peerID: MCPeerID!) {
// Called when a peer sends an NSData to us
// This needs to run on the main queue
dispatch_async(dispatch_get_main_queue()) {
var msg = NSString(data: data, encoding: NSUTF8StringEncoding)
//self.updateChat(msg, fromPeer: peerID)
}
}
// The following methods do nothing, but the MCSessionDelegate protocol
// requires that we implement them.
func session(session: MCSession!,
didStartReceivingResourceWithName resourceName: String!,
fromPeer peerID: MCPeerID!, withProgress progress: NSProgress!) {
// Called when a peer starts sending a file to us
}
func session(session: MCSession!,
didFinishReceivingResourceWithName resourceName: String!,
fromPeer peerID: MCPeerID!,
atURL localURL: NSURL!, withError error: NSError!) {
// Called when a file has finished transferring from another peer
}
func session(session: MCSession!, didReceiveStream stream: NSInputStream!,
withName streamName: String!, fromPeer peerID: MCPeerID!) {
// Called when a peer establishes a stream with us
}
func session(session: MCSession!, peer peerID: MCPeerID!,
didChangeState state: MCSessionState) {
// Called when a connected peer changes state (for example, goes offline)
}
}
Much of the code are from source codes I found on the internet, so that's why all the comments.Thanks
//Anton

Resources