Background Xcode Version 8.2 (8C38)
ios 10.2 for iPhone 7 plus - Simulator
I got this working in objective-c and I'm now trying to get it to work in swift. The code compiles and runs, but when the buttons are clicked the label doesn't change. If the label was updating I would post it on CR rather than here.
It started out as an interview take home question, but the objective-c portion got me the onsite interview. I'm pursing this to learn more about swift. Interview question
/*
* Create a static library or iOS Framework using Objective-C that performs the following 3 functions:
* - Collects the GPS location (latitude and longitude) of the user at a point in time
* - Collects the battery state and returns whether or not the device is plugged in and what percentage of life is left.
* - Accesses any publicly available, free API to collect the data of your choice and returns it
* (this should be a network call)
*
* Build a simple application with 3 buttons and a label where text can be displayed. Each button should call into the
* three functions of the library described above and output the response to the label. Your application should consist
* of two tabs, one written in Objective-C and one written in Swift. Both tabs should call into the same Objective-C
* library and perform the same function.
*
* Only use Apple frameworks to complete this task. Fully comment your code explaining your logic and choices where multiple
* choices are available. For example, Apple provides numerous ways to retrieve a network resource, document why you choose
* the solution you did.
*/
This may be a duplicate question, but I'm not sure I have looked at The following questions:
- Swift Update Label (with HTML content) takes 1min
- Concurrent vs serial queues in GCD
- How to create dispatch queue in Swift 3
- Swift 3 warning for dispatch async
I'm not sure if the problem is in the async call I make, in my creation of the button itself, or the property/var declarations at the top.
import UIKit
class ViewController: UIViewController {
var getGPSLongitudeAndLatitudeWithTimeStamp : UIButton?
var getBatteryLevelAndState : UIButton?
var getNextorkImplementation : UIButton?
var displayButtonAction : UILabel?
// The following variables are used in multiple functions. They are constant during the display of the super view
// and control the size of the subviews
var selfWidth : CGFloat = 0.0
var buttonHeight : CGFloat = 0.0
var viewElementWidth : CGFloat = 0.0
var buttonYCenterOffset : CGFloat = 0.0 // The y center should be half the value of the height
var buttonXCenter : CGFloat = 0.0 // Center the button title relative to the width of the button and the width of the super view
var buttonXInit : CGFloat = 0.0
var buttonVerticalSeparation : CGFloat = 0.0
var startingVerticalLocation : CGFloat = 0.0
var displayLabelHeight: CGFloat = 50.0
func initFramingValuesOfMyDisplay() {
selfWidth = self.view.bounds.size.width
buttonHeight = 20.0 // This should be programmable in relative to self.view.bounds.size.height
viewElementWidth = 0.8 * selfWidth;
buttonYCenterOffset = buttonHeight / 2.0; // The y center should be half the value of the height
buttonXCenter = selfWidth / 2.0; // Center the button title relative to the width of the button and the width of the super view
buttonXInit = 0.0;
buttonVerticalSeparation = buttonHeight + buttonYCenterOffset;
startingVerticalLocation = 430.0; // 430 was chosen based on experimentation in the simulator
}
func setLabelWithGPSLatitudeAndLongitudeWithTimeStampData()
{
var actionString : String = "Testing Label Text"
actionString = "GPS Button Action Failure: Data Model not created";
DispatchQueue.global().async {
self.displayButtonAction?.text = actionString
}
}
func setLabelWithBatteryLevelAndState() {
var actionString : String = "Get Battery Level and State";
actionString = "Battery Button Action Failure: Data Model not created"
DispatchQueue.global().async {
self.displayButtonAction?.text = actionString
}
}
func setLabelActionNetwork() {
var actionString :String = "Fake Button set to American Express Stock Price";
actionString = "Network Button Action Failure: Data Model not created";
DispatchQueue.global().async {
self.displayButtonAction?.text = actionString
}
}
func makeAButton(yButtonStart : CGFloat, buttonTitle: String, underSubview: UIButton?) -> UIButton
{
let thisButton = UIButton.init(type: .system)
thisButton.frame = CGRect(x: buttonXInit, y: yButtonStart, width: viewElementWidth, height: buttonHeight)
thisButton.setTitle(buttonTitle, for:UIControlState.normal)
thisButton.backgroundColor = UIColor.yellow
thisButton.setTitleColor(UIColor.black, for: UIControlState.normal)
if ((underSubview) == nil) {
self.view.addSubview(thisButton)
}
else {
self.view.insertSubview(thisButton, belowSubview:underSubview!)
}
return thisButton;
}
func makeALabel(yLabelStart : CGFloat, underSubview: UIButton?) -> UILabel
{
let thisLabel = UILabel.init()
thisLabel.frame = CGRect(x: selfWidth * 0.1, y: yLabelStart, width: viewElementWidth, height: displayLabelHeight)
thisLabel.font = thisLabel.font.withSize(12)
thisLabel.lineBreakMode = .byWordWrapping;
thisLabel.numberOfLines = 0;
thisLabel.textAlignment = NSTextAlignment.center;
thisLabel.textColor = UIColor.black;
if ((underSubview) == nil) {
self.view.addSubview(thisLabel)
}
else {
self.view.insertSubview(thisLabel, belowSubview:underSubview!)
}
return thisLabel;
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = UIColor.white
initFramingValuesOfMyDisplay()
addButtonAndLabels()
}
func addButtonAndLabels() -> Void {
if (selfWidth < 1.0) {
return;
}
var viewElementVerticalLocation: CGFloat = startingVerticalLocation;
// var touchUpInside : UIControlEvents = touchUpInside;
let getGPSLongitudeAndLatitudeWithTimeStamp : UIButton = makeAButton(yButtonStart: viewElementVerticalLocation, buttonTitle: "Get GPS Location with TimeStamp", underSubview: nil)
getGPSLongitudeAndLatitudeWithTimeStamp.addTarget(self, action: #selector(setLabelWithGPSLatitudeAndLongitudeWithTimeStampData), for: .touchUpInside)
viewElementVerticalLocation += buttonVerticalSeparation
let getBatteryLevelAndState : UIButton = makeAButton(yButtonStart: viewElementVerticalLocation, buttonTitle: "Get Battery Level and State", underSubview: getGPSLongitudeAndLatitudeWithTimeStamp)
getBatteryLevelAndState.addTarget(self, action: #selector(setLabelWithBatteryLevelAndState), for: .touchUpInside)
viewElementVerticalLocation += buttonVerticalSeparation
let getNextorkImplementation : UIButton = makeAButton(yButtonStart: viewElementVerticalLocation, buttonTitle: "Get Battery Level and State", underSubview: getBatteryLevelAndState)
getNextorkImplementation.addTarget(self, action: #selector(setLabelWithBatteryLevelAndState), for: .touchUpInside)
viewElementVerticalLocation += buttonVerticalSeparation
let displayButtonAction = makeALabel(yLabelStart: viewElementVerticalLocation, underSubview: getNextorkImplementation)
displayButtonAction.text = "No Action Yet"
}
required init(coder aDecoder: NSCoder) {
super.init(nibName: nil, bundle: nil)
initFramingValuesOfMyDisplay()
}
}