UISwitch switched off by user but is still programatically on - ios

I am experimenting with UISwitches on xcode using Swift. I have it to where there is a handful of Company names and their corresponding on and off switches. From top to bottom, if the user switches for example, "Google" Switch on, then they are able to view the chosen companies facebook and twitter. If they choose another company, once they turn that switch on for example "Samsung" , the Google switch turns off then the user is able to see Samsungs facebook and twitter page.
My issue is... from top to bottom, it works fine. Im able to see both pages from Google to samsung. But if I go from samsung back to Google, the google switch is on but it still shows samsung's pages. But, if I switch the saumsung switch on,off then go to google, it works fine.
My assumption is that while the switch visually looks off once another switch is turned on from bottom to top, it is still programmatically on
I'm wondering if people have had a similar issue. If not, I hope this helps those in the future if they find themselves in a similar situation
Here is my main view Controller
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var GoogleSwitch: UISwitch!
#IBOutlet weak var SamsungSwitch: UISwitch!
#IBOutlet weak var FordSwitch: UISwitch!
#IBOutlet weak var ToyotaSwitch: UISwitch!
#IBOutlet weak var SquareEnixSwitch: UISwitch!
#IBOutlet weak var ABCBankSwitch: UISwitch!
var Google: Bool = false
var Samsung: Bool = false
var Ford: Bool = false
var Toyota:Bool = false
var SquareEnix :Bool = false
var ABCBank :Bool = false
override func viewDidLoad() {
super.viewDidLoad()
// ABCBankSwitch.addTarget(self, action: Selector("switchIsChanged:"), forControlEvents: UIControlEvents.ValueChanged)
// 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.
}
#IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true
{
GoogleSwitch.on = true
SamsungSwitch.on = false
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
Google = true
// GoogleSwitch.on = true
}
else
{ Google = false
sender.on = false
}
// sender.on = false
}
#IBAction func ActiveSamsung(sender: UISwitch) {
if sender.on == true
{
GoogleSwitch.on = false
SamsungSwitch.on = true
FordSwitch.on = false
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
Samsung = true
}
else
{sender.on = false
Samsung = false}
}
#IBAction func ActiveFord(sender: UISwitch) {
if sender.on == true
{Ford = true
GoogleSwitch.on = false
SamsungSwitch.on = false
FordSwitch.on = true
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
}
else
{ if sender.on == false {
Ford = false}
}
}
#IBAction func ActiveToyota(sender: UISwitch) {
if sender.on == true
{ Toyota = true
GoogleSwitch.on = false
SamsungSwitch.on = false
FordSwitch.on = false
ToyotaSwitch.on = true
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
}
else
{ Toyota = false}
}
#IBAction func ActiveEnix(sender: UISwitch) {
if sender.on == true
{ SquareEnix = true
GoogleSwitch.on = false
SamsungSwitch.on = false
FordSwitch.on = false
ToyotaSwitch.on = false
//SquareEnixSwitch.on = true
ABCBankSwitch.on = false
}
else
{ SquareEnix = false
// sender.on = false
}
}
#IBAction func ActiveABC(sender: UISwitch) {
if sender.on == true
{ ABCBank = true
ABCBankSwitch.setOn(true, animated: true)
GoogleSwitch.on = false
SamsungSwitch.on = false
FordSwitch.on = false
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
}
}
else
{
ABCBankSwitch.setOn(false, animated: true)
ABCBank = false
// sender.on = false
}
}
}
here is my FacebookViewController. (not putting the twitter on as it is almost identical to the facebook one)
import UIKit
class FacebookViewController: UIViewController{
var webAddress: String = ""
#IBOutlet weak var CompanyFB: UIWebView!
override func viewWillAppear(animated: Bool) {
let myCompany: ViewController = self.tabBarController!.viewControllers![0] as! ViewController
let showGoogle: Bool = myCompany.Google
let showSamsung: Bool = myCompany.Samsung
let showFord: Bool = myCompany.Ford
let showToyota: Bool = myCompany.Toyota
let showEnix: Bool = myCompany.SquareEnix
let showBank:Bool = myCompany.ABCBank
if showGoogle {
webAddress = "https://www.facebook.com/Google/"
//myCompany.GoogleSwitch.on = false had this to test. either way is still doesnt work
// CompanyFB.loadRequest(NSURLRequest(URL: NSURL(string: webAddress)!))
}
if showSamsung {
webAddress = "https://www.facebook.com/SamsungUSA"
// myCompany.SamsungSwitch.on = false
// CompanyFB.loadRequest(NSURLRequest(URL: NSURL(string: webAddress)!))
}
if showFord {
webAddress = "https://www.facebook.com/ford/"
// CompanyFB.loadRequest(NSURLRequest(URL: NSURL(string: webAddress)!))
}
if showToyota {
webAddress = "https://www.facebook.com/toyota"
// CompanyFB.loadRequest(NSURLRequest(URL: NSURL(string: webAddress)!))
}
if showEnix {
webAddress = "https://www.facebook.com/SquareEnix"
}
if showBank {
webAddress = "https://www.facebook.com/ABC-Bank-132047286857188/"
}
CompanyFB.loadRequest(NSURLRequest(URL: NSURL(string: webAddress)!))
}
override func viewDidLoad() {
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.
}
}

Your problem is that you aren't keeping your separate booleans in sync with your switches. Consider this code:
#IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true {
GoogleSwitch.on = true
SamsungSwitch.on = false
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
Google = true
}
else {
Google = false
sender.on = false
}
}
If I change the "Google" switch then then Google variable will be set to true/false accordingly. This code also turns off all of the other switches, but it doesn't change the boolean associated variables. So, if after selecting Google I then select "Samsung", the Google switch will be turned off but the Google variable will still be true.
You could use a computed property rather than the separate booleans:
var Google: Bool {
return self.GoogleSwitch.on
}
and so on.
Also, by convention variables and functions should start with a lower case letter, so it should be var google and func activateGoogle

There are a few things going on here, some unrelated to your problem, but I'll comment on them as well so you can improve as a coder.
1) Convention for Swift dictates that you name variables and methods starting with a lower case letter. So GoogleSwitch should be googleSwitch etc. Also, try and be descriptive with the names. In your FacebookViewController you have a variable myCompany for the ViewController class. First, the class should be called something like MyCompanyViewController so you know which view controller it is. And then the myCompany variable could be called myCompanyViewController. CompanyFB should be something like companyFBWebView.
2) You can really simply your code a lot here. Use a single IBAction for all of the switches. A common problem (which may be an issue here), is when you copy and paste controls in Interface Builder, it sometimes will copy the actions assigned as well, and then you add another, so it calls two methods each time it's switched. By using a single method, you save a tonne of duplicated code and avoid this problem.
Your entire first ViewController class can be condensed to this (then connect all of your switches to the same IBOutlet switchToggled::
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var googleSwitch: UISwitch!
#IBOutlet weak var samsungSwitch: UISwitch!
#IBOutlet weak var fordSwitch: UISwitch!
#IBOutlet weak var toyotaSwitch: UISwitch!
#IBOutlet weak var squareEnixSwitch: UISwitch!
#IBOutlet weak var abcBankSwitch: UISwitch!
#IBAction func switchToggled(sender: UISwitch) {
// Remember the state of the triggered switch because we're about to turn it off
let newState: Bool = sender.on
googleSwitch.on = false
samsungSwitch.on = false
fordSwitch.on = false
toyotaSwitch.on = false
squareEnixSwitch.on = false
abcBankSwitch.on = false
// Restore the state of the switch
sender.on = newState
}
}
3) Avoid using duplicate variables for the same thing, the Bool for Google etc should be the same as the switch, so just use the switch.on value. Edit: (or as Paulw11 mentioned, use a calculated property).
4) When using an if to test a variable state, or multiple variable states as you're doing in the FacebookViewController class, when only one possible case should happen, use else if instead of multiple if's. In your case, you're triggering two or more cases at once (due to your other bugs). If you used else if clauses, you'd only ever trigger one and you likely would have narrowed down your other bug earlier.
if showGoogle {
webAddress = "https://www.facebook.com/Google/"
}
else if showSamsung {
webAddress = "https://www.facebook.com/SamsungUSA/"
}
...
5) Expanding on #4 you could change this to make use of Swift's powerful enum features.
import UIKit
class FacebookViewController: UIViewController {
enum Company: String {
case Google = "https://www.facebook.com/Google/"
case Samsung = "https://www.facebook.com/SamsungUSA/"
case Ford = "https://www.facebook.com/ford/"
case Toyota = "https://www.facebook.com/toyota/"
case SquareEnix = "https://www.facebook.com/SquareEnix/"
case ABCBank = "https://www.facebook.com/ABC-Bank-132047286857188/"
}
var company: Company = .Google // Default to Google
#IBOutlet weak var companyFBWebView: UIWebView!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let myCompanyViewController: ViewController = self.tabBarController!.viewControllers![0] as! ViewController
if myCompanyViewController.googleSwitch.on {
company = .Google
}
else if myCompanyViewController.samsungSwitch.on {
company = .Samsung
}
else if myCompanyViewController.fordSwitch.on {
company = .Ford
}
else if myCompanyViewController.toyotaSwitch.on {
company = .Toyota
}
else if myCompanyViewController.squareEnixSwitch.on {
company = .SquareEnix
}
else if myCompanyViewController.abcBankSwitch.on {
company = .ABCBank
}
if let url = NSURLRequest(URL: NSURL(string: company.rawValue)) {
companyFBWebView.loadRequest(url)
}
}
}
6) In Swift, avoid using ! like the plague. Ideally you'll only use it for IBOutlet's and other cases you know for certain a value exists. The line let myCompanyViewController: ViewController = self.tabBarController!.viewControllers![0] as! ViewController is likely to crash in some cases. Possibly due to timing issues, or other changes you may make to the code down the road. Safer to check the options with if let and handle the error gracefully.
7) I just noticed another issue as I was proofreading. Anytime* you override a method from a super class, make sure you also call the super's version. So your viewWillAppear(animated:) etc calls need to call the super version or you can get really weird, hard to track down bugs.
I put a star on Anytime in #7 because there are some cases where you intentionally don't want to call the super method, but those are rare and you'll know it when the time comes.

I'm assuming your IBActions are hooked up to the ValueChanged event, and you expect them to fire in two instances: when you change the switch by touching it; or when you change the value of the on property.
If so, the problem is that the event does not fire in the second case, only the first. Therefore, once Google is set to true, the only way it gets set back to false is by touching the switch to off.
Since your model only wants one switch to be on, you could instead have one variable containing the switch that should be on. When you touch a switch, just update that one variable and redisplay all of them. Using an enum for this variable would be helpful. Along the lines of:
enum Switches {
case None
case Google
case Samsung
}
var onSwitch = Switches.None
Then code in each IBAction along the lines of:
#IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true {
onSwitch = Switches.Google
updateSwitches()
}
}
And updateSwitches looks like:
func updateSwitches() {
GoogleSwitch.on = (onSwitch == Switches.Google)
SamsungSwitch.on = (onSwitch == Switches.Samsung)
}

Related

How to add an alert to switch toggle for multiple answers?

I created a Quiz app. There is one question with five answers, where the user can choose one of them. However at the moment it's possible to choose more than one answer. How can I add an alert (UIAlertController) and a restriction so if the user has already chosen one answer and tries to choose a second one ?
var questionIndex = 0
var answersChosen: [Answer] = []
func updateUI() {
let currentQuestion = questions[questionIndex]
let currentAnswers = currentQuestion.answers
let totalProgress = Float(questionIndex) /
Float(questions.count)
numberOfQuestion.text = "\(questionIndex+1)/5"
// navigationItem.title = "Вопрос - \(questionIndex+1)"
mainQuestion.text = currentQuestion.text
progressBar.setProgress(totalProgress, animated:
true)
updateMultipleStack(using: currentAnswers)
}
#IBAction func multipleAnswerButtonPressed(_ sender: Any) {
let currentAnswers = questions[questionIndex].answers
if firstSwitch.isOn {
answersChosen.append(currentAnswers[0])
}
if secondSwitch.isOn {
answersChosen.append(currentAnswers[1])
}
if thirdSwitch.isOn {
answersChosen.append(currentAnswers[2])
}
if fourthSwitch.isOn {
answersChosen.append(currentAnswers[3])
}
if fifthSwitch.isOn {
answersChosen.append(currentAnswers[4])
}
nextQuestion()
}
func updateMultipleStack(using answers: [Answer]) {
firstSwitch.isOn = false
secondSwitch.isOn = false
thirdSwitch.isOn = false
fourthSwitch.isOn = false
fifthSwitch.isOn = false
firstQuestionLbl.text = answers[0].text
secondQuestionLbl.text = answers[1].text
thirdQuestionLbl.text = answers[2].text
fourthQuestionLbl.text = answers[3].text
fifthQuestionLbl.text = answers[4].text
}
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
if segue.identifier == "ResultSegue" {
let resultsViewController = segue.destination as! ResultViewController
resultsViewController.responses = answersChosen
}
}
}
The approach I'd take would be to separate the user's selection of an answer (UISwitch collection) from processing the selected answer(Submit Answer button). This would allow the user to change their answer. The previous selection is automatically cleared. The answer is final when pressing a "Submit Answer" button (not shown).
In this code example, the switches are set as an IBOutlet collection. The tag on each switch is set from 0 to 4. All the switches are connected to an IBAction called switchPressed. A variable called selectedAnswer is used to identify the user's final picked answer when the "Submit Answer" is pressed.
#IBOutlet var switches: [UISwitch]!
private let noAnswer = -1
private var selectedAnswer = -1
#IBAction func switchPressed(_ sender: UISwitch) {
// Check if user turned off switch
guard sender.isOn == true else {
selectedAnswer = noAnswer
return
}
// Get user's answer and set all switches
selectedAnswer = sender.tag
switches.forEach { $0.isOn = false }
sender.isOn = true
}
#IBAction func submitAnswer(_ sender: UIButton) {
guard selectedAnswer > noAnswer else { return }
// use selectedAnswer to process answer and go to the next question
answersChosen.append(currentAnswers[selectedAnswer])
}
You could store all the switches in an array named Switches for example and then run a for loop to check if more than one is selected when checking answer.
var count = 0
for switchToggle in switches {
if switchToggle.isOn {
count += 1
if count > 1 {
//Print Warning "only select one"
}
} else {
//append answers
}
}
you could also use this to have multiple answers for certain quiz question
For the warning, you have different options you could use. You could use UIAlertController to display a warning if more than one button is selected but this could become annoying for the user after a while.
Another option could be to use a UILabel which warns the user to only pick one answer. You could animate the label to fade away after a few seconds.

How can i handle the multiple click action to single button for api calling and get the true response from api

i just want to know the method to handle multiple click event on single button.(e.g FACEBOOK like button if i tapped multiple time then it may work perfect)
below code give you some idea and if there is any appropriate solution then give me as soon as possible.
class LikeViewController: UIViewController {
//MARK:- Outlets
#IBOutlet weak var btnLike: UIButton!
#IBOutlet weak var lblDescription: UILabel!
//MARK:- Variables
var objModelWatchList:WatchListModel?
var objUser = WatchListModel()
//MARK:- Lifecycle methods
override func viewDidLoad() {
super.viewDidLoad()
getWatchList()
}
//MARK:- Functions
//Function for prepare UI
func prepareUI() {
btnLike.isSelected = isLike()
}
//Function for prepare data from api
func getWatchList() {
objUser.videoId = 216
objUser.type = "VIDEO"
APIService.sharedInstance.getWatchList(parameters: objUser.toDictionary() as [String : AnyObject], success: { (dataSuccess) -> (Void) in
self.objModelWatchList = dataSuccess
DispatchQueue.main.async {
self.prepareUI()
self.lblDescription.text = self.objModelWatchList?.message
}
}) { (resultFailure) -> (Void) in
print(resultFailure)
}
}
//Function to varify the status of like
func isLike() -> Bool {
return objModelWatchList!.status == 1 ? true : false
}
//MARK:- Actions
#IBAction func btnLikeClicked(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
self.getWatchList()
}
}
Thank You.
You have to disable your button when API call and when u will get right response after the processing on that response you have to enable it.
Its works for me. I have a same issue.
if you refer to manage several events taps...I recommend that use tapGestureRecognizer or variants, these can manage events that you comment for example...:
Single tap,double tap or more taps to trigger function event
Hold tap [UILongPressGestureRecognizer]
if you refer to same button called severals function in diferents situations i recommend the use un tag button for example:
function examplefunctionA(){
//Another Proccess
//Another Proccess
self.button.tag = 2
}
function examplefunctionB(){
//Another Proccess
//Another Proccess
self.button.tag = 1
}
func buttonclicked(sender: UIButton) {
if sender.tag == 1 {
examplefunctionA()
}else if sender.tag == 2 {
examplefunctionB()
}
}

View is not being updated when calling UIButton.isHidden = true/false

I am using xcode 8.2 and swift to make a simple application.
I have added a UIButton to my View using the Interface Builder.
I have added the appropriate outlets for the button:
#IBOutlet weak var myBtn: UIButton!
I want this button to be hidden on start so in viewDidLoad I am setting is to Hidden. Like this:
override func viewDidLoad() {
super.viewDidLoad()
...
myBtn.isHidden = true
...
mqttConfig = MQTTConfig(clientId: "iphone7", host: "192.xx.xx.150", port: 18xx, keepAlive: 60)
mqttConfig.onMessageCallback = { mqttMessage in
if ( mqttMessage.topic == "status" ) {
if ( mqttMessage.payloadString?.localizedStandardContains("show") )! {
self.showButton = true
} else if ( mqttMessage.payloadString?.localizedStandardContains("hide") )! {
self.showButton = false
}
self.showHideSeatButtons()
} else {
// something to do in case of other topics
}
}
Later in the code I have a function to show/hide this button.
func showHideButton(){
if ( self.showButton ) {
print("button enabled!")
myBtn.isHidden = false
} else {
print("button disabled!")
myBtn.isHidden = true
}
}
When I call this function (by receiving a certain message using MQTT) I get the print outs but I don't see the button.
If I press where I know the button is, then the button gets shown.
Any idea what could be going on here? I have spent and hour googling this now! Please don't suggest object-c way of solving this issue, as I don't know object-c.
In onMessageCallback block
Replace following line
self.showHideSeatButtons()
with
DispatchQueue.main.async {
self.showHideSeatButtons()
}
Note: UI related changes/updates must be handled by main queue (thread).
Since you're calling a service it's possible you're not working in the same thread. Try this:
func showHideButton(){
DispatchQueue.main.async {
if (self.showButton ) {
print("button enabled!")
self.myBtn.isHidden = false
} else {
print("button disabled!")
self.myBtn.isHidden = true
}
}
}
try this
myBtn.isHidden = true
myBtn.alpha = 0

Errors while implementing Chromecast in swift 3

I seem to have a problem implementing ChromeCast features in a project of mine.
I have been trying to implement the GCKDeviceScannerListener Singleton Class on a UIViewController, however its delegate methods are not getting called.
The deviceDidComeOnline method of GCKDeviceScannerListener never gets called.
Instead I have a bunch of error displayed by the chromeCast logger as followed:
+[NSMutableDictionary(GCKAdditions) gck_loadFromCacheWithName:] - Device cache file file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_nearby_devices.plist doesn't exist.
+[NSMutableDictionary(GCKAdditions) gck_loadFromCacheWithName:] - Device cache file file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_network_cache.plist doesn't exist.
scanning started
+[NSMutableDictionary(GCKAdditions) gck_deleteCacheWithName:] - Device cache file file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_device_cache.plist doesn't exist.
+[NSMutableDictionary(GCKAdditions) gck_deleteCacheWithName:] - Device cache file file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_device_cache_v1.plist doesn't exist.
+[NSMutableDictionary(GCKAdditions) gck_deleteCacheWithName:] - Device cache file file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_device_cache_v2.plist doesn't exist.
+[NSMutableDictionary(GCKAdditions) gck_loadFromCacheWithName:] - Device cache file
file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_device_cache_v3.plist doesn't exist
I can't seem to figure out why I have these errors. But it seems that the deviceScanner never even finds my receiver device.
My viewController code is:
class ChromeCastViewController: UIViewController, GCKDeviceScannerListener, GCKDeviceManagerDelegate, GCKMediaControlChannelDelegate{
fileprivate let kCancelTitle = "Cancel"
fileprivate let kDisconnectTitle:String! = "Disconnect"
// Publicly available receiver to demonstrate sending messages - replace this with your
// own custom app ID.
fileprivate let kReceiverAppID = "XXXXXXXXX"
fileprivate lazy var btnImage:UIImage = {
return UIImage(named: "icon-cast-identified.png")!
}()
fileprivate lazy var btnImageselected:UIImage = {
return UIImage(named: "icon-cast-connected.png")!
}()
fileprivate var deviceScanner:GCKDeviceScanner?
fileprivate var deviceManager:GCKDeviceManager?
fileprivate var mediaInformation:GCKMediaInformation?
fileprivate var selectedDevice:GCKDevice?
#IBOutlet weak var googleCastButton: UIBarButtonItem!
#IBOutlet weak var backButton: UIBarButtonItem!
#IBAction func backAction(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
self.startScan()
}
func startScan() {
let filterCriteria = GCKFilterCriteria(forAvailableApplicationWithID: kReceiverAppID)
self.deviceScanner = GCKDeviceScanner(filterCriteria: filterCriteria)
if let deviceScanner = self.deviceScanner {
deviceScanner.add(self)
deviceScanner.startScan()
print("scanning started")
deviceScanner.passiveScan = true
}
}
// MARK: GCKDeviceScannerListener
func deviceDidComeOnline(_ device: GCKDevice) {
print("deviceDidComeOnline")
print("Device found: \(device.friendlyName)");
self.updateButtonStates()
}
func deviceDidGoOffline(_ device: GCKDevice) {
print("deviceDidGoOffline()")
print("Device went away: \(device.friendlyName)");
self.updateButtonStates()
}
func deviceDidChange(_ device: GCKDevice) {
print("deviceDidChange()");
}
func updateButtonStates() {
print("updateButton")
if (deviceScanner!.devices.count > 0) {
// Show the Cast button.
navigationItem.rightBarButtonItems = [googleCastButton!]
if (deviceManager != nil && deviceManager?.connectionState == GCKConnectionState.connected) {
// Show the Cast button in the enabled state.
googleCastButton!.tintColor = UIColor.blue
} else {
// Show the Cast button in the disabled state.
googleCastButton!.tintColor = UIColor.gray
}
} else{
// Don't show Cast button.
navigationItem.rightBarButtonItems = []
}
}
}
Thank you in advance for any help or tips you can give me.
Best regards
UPDATE:
I have modified my code base to follow google v3 guidelines.
I now instantiate a GCKCastContext in AppDelegate in order to use google widgets.
But It seems that GCKCastContext or functionalities associated with the singleton are never called after initialising it. I have tried to add the GCKDiscoveryManagerListener to my AppDelegate to see if was detecting my ChromeCast device.
The code for my AppDelegate is :
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GCKLoggerDelegate,GCKDiscoveryManagerListener {
var window: UIWindow?
fileprivate let kReceiverAppID = "XXXXXXXXXX"
var discoveryManager: GCKDiscoveryManager
override init(){
let options:GCKCastOptions = GCKCastOptions(receiverApplicationID: kReceiverAppID)
GCKCastContext.setSharedInstanceWith(options)
self.discoveryManager = GCKCastContext.sharedInstance().discoveryManager
super.init()
self.discoveryManager.add(self)
self.discoveryManager.passiveScan = true
self.discoveryManager.startDiscovery()
GCKLogger.sharedInstance().delegate = self
}
.....
func log(fromFunction function: UnsafePointer<Int8>, message: String) {
let functionName = String(cString: function)
print(functionName + " - " + message);
}
func didUpdateDeviceList() {
print("didUpdateDeviceList with \(discoveryManager.deviceCount) devices")
(0..<discoveryManager.deviceCount).forEach { index in
print(index, discoveryManager.device(at: index))
}
}
func didStartDiscoveryForDeviceCategory(deviceCategory: String) {
print("GCKDiscoveryManagerListener: \(deviceCategory)")
print("FOUND: \(self.discoveryManager.hasDiscoveredDevices)")
}
func willUpdateDeviceList(){
print("will update device was called")
}
}
The functions didUpdateDeviceList, didStartDiscoveryForDeviceCategory
, willUpdateDeviceList are never called, meaning no Chrome device is ever found making the widgets unusable.
Thank again for any help

UITextField always nil

I'm updating some example code to the latest version of both Swift (from beta 4 to 1.2) and also the latest version of Couchbase Lite.
I'm having an issue with a UITextField always being nil. I've checked that its connected in the IB / xib file. I've disconnected and reconnected it to the UITextField object addItemTextField.
Its declared as
#IBOutlet weak var addItemTextField: UITextField!
and the relevant functions:
func configureView() {
// Update the user interface for the detail item.
if let detail: AnyObject = self.detailItem {
if let label = self.detailDescriptionLabel {
label.text = detail.description
}
title = detail.title
assert(addItemTextField != nil, "addItemTextField cannot be nil") // <- always hits this assertion
addItemTextField.enabled = true
addImageButton.enabled = true
navigationItem.rightBarButtonItem!.title = "Share"
assert(dataSource != nil, "detail.dataSource not connected")
dataSource!.labelProperty = "title"
dataSource!.query = detail.queryTasks().asLiveQuery()
} else {
title = nil
addImageButton.enabled = false
addItemTextField.enabled = false
}
}
override func viewDidLoad() {
app = UIApplication.sharedApplication().delegate as? AppDelegate
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.configureView()
}
The ViewController its part of is instantiated with
performSegueWithIdentifier("showDetail", sender: self)
(and of course i've checked the identifier is correctly set in the xib file)
Is there something I might have missed here?

Resources