Swift "Thread 1: EXC_BAD_INSTRUCTION(code=EXC-I386_INVOP,subcode=0x0)" when using keyBoardWillShow - xcode

I am trying to let a user click on a cell in a tale view and it brings them to the DetailViewController. The only problem is that each time I try to do this the error "Thread 1: EXC_BAD_INSTRUCTION(code=EXC-I386_INVOP,subcode=0x0)" comes up.
This is in the DetailViewController:
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyBoardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
//FIRST ERROR HERE
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyBoardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
//SECOND ERROR HERE
/* Setup the contentInsets */
self.tableView.contentInset = UIEdgeInsetsZero
self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero
self.edgesForExtendedLayout = UIRectEdge.None
/* Make sure the content doesn't go below tabbar/navbar */
self.extendedLayoutIncludesOpaqueBars = true
self.automaticallyAdjustsScrollViewInsets = false
/* Setup Map */
let geo = party?.objectForKey("location") as PFGeoPoint
//THIRD ERROR HERE
let coordinate = CLLocationCoordinate2D(latitude: geo.latitude, longitude: geo.longitude)
let reg = MKCoordinateRegionMakeWithDistance(coordinate, 1500, 1500)
self.mapView.setRegion(reg, animated: true)
self.mapView.showsUserLocation = true
if(party?.objectForKey("comments") != nil) {
comments = party?.objectForKey("comments") as? [String]
}
println(party)
println(party?.objectForKey("Name"))
self.nameLabel.text = party?.objectForKey("Name") as? String
// Do any additional setup after loading the view.
}
The other issue is that even after I put // in front of keyBoardWillShow the same error happens for keyBoardWillHide. And if I cover that I get once again the same error trying to setup a map view. As you can probably see, I am just getting into swift, xcode, and Parse and I have no idea what I really and doing. Any help is appreciated.

Related

Unable to detect QR Code

I have tried to make an app scanning the QR code within ios 10 and Swift 3. However, my QRScannerController could not detect the QR Code but showing the camera view.
I don't understand what's wrong with the code. Here is the implement of the controller:
import UIKit
import AVFoundation
class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
#IBOutlet var messageLabel:UILabel!
#IBOutlet var topbar: UIView!
//TESTING
var captureSession: AVCaptureSession?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var qrCodeFrameView: UIView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Get an instance of the AVCaptureDevice class to initialize a device object and provide the video as the media type parameter
let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
do {
view.bringSubview(toFront: messageLabel)
view.bringSubview(toFront: topbar)
// Get an instance of the AVCaptureDeviceInput class using the previous deivce object
let input = try AVCaptureDeviceInput(device: captureDevice)
// Initialize the captureSession object
captureSession = AVCaptureSession()
// Set the input devcie on the capture session
captureSession?.addInput(input)
// Initialize a AVCaptureMetadataOutput object and set it as the input device
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession?.addOutput(captureMetadataOutput)
// Set delegate and use the default dispatch queue to execute the call back
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
captureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
//Initialise the video preview layer and add it as a sublayer to the viewPreview view's layer
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
videoPreviewLayer?.frame = view.layer.bounds
view.layer.addSublayer(videoPreviewLayer!)
//start video capture
captureSession?.startRunning()
//Initialize QR Code Frame to highlight the QR code
qrCodeFrameView = UIView()
if let qrCodeFrameView = qrCodeFrameView {
qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
qrCodeFrameView.layer.borderWidth = 2
view.addSubview(qrCodeFrameView)
view.bringSubview(toFront: qrCodeFrameView)
}
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
// Check if the metadataObjects array is not nil and it contains at least one object.
if metadataObjects == nil || metadataObjects.count == 0 {
qrCodeFrameView?.frame = CGRect.zero
messageLabel.text = "No QR code is detected"
return
}
// Get the metadata object.
let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
if metadataObj.type == AVMetadataObjectTypeQRCode {
// If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
qrCodeFrameView?.frame = barCodeObject!.bounds
if metadataObj.stringValue != nil {
messageLabel.text = metadataObj.stringValue
}
}
}
} catch {
//If any error occurs, simply print it out
print(error)
return
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
Your message label is going under your view controller view. Just bring the message label to front at the end of view did load would help.
I have created a sample project and it was working fine on iPhone. Please take a look at here

How can I rename label with another class attribute?

So, here is the part of class OnboardingViewController, where declared and initialized reviewConsentStep.
class OnboardingViewController: UIViewController {
// MARK: IB actions
#IBAction func joinButtonTapped(sender: UIButton) {
let consentDocument = ConsentDocument()
let consentStep = ORKVisualConsentStep(identifier: "VisualConsentStep", document: consentDocument)
let healthDataStep = HealthDataStep(identifier: "Health")
let signature = consentDocument.signatures!.first!
let reviewConsentStep = ORKConsentReviewStep(identifier: "ConsentReviewStep", signature: signature, inDocument: consentDocument)
reviewConsentStep.text = "Review the consent form."
reviewConsentStep.reasonForConsent = "Consent to join the Developer Health Research Study."
let passcodeStep = ORKPasscodeStep(identifier: "Passcode")
passcodeStep.text = "Now you will create a passcode to identify yourself to the app and protect access to information you've entered."
let completionStep = ORKCompletionStep(identifier: "CompletionStep")
completionStep.title = "Welcome aboard."
completionStep.text = "Thank you for joining this study."
let orderedTask = ORKOrderedTask(identifier: "Join", steps: [consentStep, reviewConsentStep, healthDataStep, passcodeStep, completionStep])
let taskViewController = ORKTaskViewController(task: orderedTask, taskRunUUID: nil)
taskViewController.delegate = self
presentViewController(taskViewController, animated: true, completion: nil)
}
I want to use reviewConsentStep.signature?.givenName and reviewConsentStep.signature?.familyName here:
#IBOutlet var applicationNameLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
applicationNameLabel.text = reviewConsentStep.signature?.givenName/////////... here
If it possible, please tell me how can I do it?

How to show route between a MKPointAnnotation and user's current location in swift 2

I am trying to show the route between a MKPointAnnotation and user's current location, but i am fail with it.
My idea is: getting user's current location -> getting the MKPointAnnotation' Coordinate -> line up with MKPolylineRenderer
The problem is that i cannot find the problem. :( I have no idea where i should modify.
class MapInSearch: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
var destination: MKMapItem?
var coords: CLLocationCoordinate2D?
let locationManager = CLLocationManager()
var PlaceLat = ""
var PlaceLong = ""// get from previous view controller
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.requestAlwaysAuthorization()
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}// step 1
self.mapView.showsUserLocation = true
self.mapView.delegate = self
self.addRoute() // step 2
}
func addRoute() {
var pointsToUse: [CLLocationCoordinate2D] = []
if PlaceLat != "" || PlaceLong != "" {
let coords = "\(PlaceLat), \(PlaceLong)"
let p = CGPointFromString(coords)
pointsToUse += [CLLocationCoordinate2DMake(CLLocationDegrees(p.x), CLLocationDegrees(p.y))]
}
pointsToUse += [CLLocationCoordinate2DMake(CLLocationDegrees(coords!.latitude), CLLocationDegrees(coords!.longitude))]
let myPolyline = MKPolyline(coordinates: &pointsToUse, count: 2)
mapView.addOverlay(myPolyline)
}
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
let lineView = MKPolylineRenderer(overlay: overlay)
lineView.strokeColor = UIColor.greenColor()
return lineView // step 3
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.coords = manager.location!.coordinate
print("locations = \(coords!.latitude) \(coords!.longitude)")
}
My code is very disorderly because i mixed 4-5 tutorials. Also, these tutorials is written with swift 1.2.(i have tried to edit it to swift 2, but i am fail)
Did you ever resolve your problem? Using the latest iteration of Swift 2 in XCode 7.3, in your view (we will call it MyViewController):
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.mapView.delegate = self
var coordinates : [CLLocationCoordinate2D] = [];
addRoute(coordinates);
}
func addRoute(coordinates: [CLLocationCoordinate2D]) {
// insert your code to populate coordinates array with your coordinates
polyLine = MKPolyline(coordinates: &coordinates, count: coordinates.count)
self.mapView.addOverlay(polyLine, level: MKOverlayLevel.AboveRoads)
}
Then in the same file:
extension MyViewController: MKMapViewDelegate {
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
let pr = MKPolylineRenderer(overlay: overlay);
pr.strokeColor = UIColor.blueColor().colorWithAlphaComponent(0.5);
pr.lineWidth = 5;
return pr;
}
}
You may find the important part was the extension. I haven't tested this code, so feel free to correct any issues that crept in.
in your CLLocationManagerDelegate delegate function didUpdateLocations you can update your location by setting
self.myLocation = locations[0] as CLLocation
Then call MakeRoute() - This is a function i wrote to either make a route by car or by walking (hence the self.driveIsSet)
func makeRoute() {
let startPlaceMark = MKPlacemark(coordinate: myLocation.coordinate)
let endPlaceMark = MKPlacemark(coordinate: restLocation.coordinate)
let startMapItem = MKMapItem(placemark: startPlaceMark)
let endMapItem = MKMapItem(placemark: endPlaceMark)
let directionRequest = MKDirectionsRequest()
directionRequest.source = startMapItem
directionRequest.destination = endMapItem
if self.driveIsSet {
directionRequest.transportType = .automobile
} else {
directionRequest.transportType = .walking
}
let directions = MKDirections(request: directionRequest)
directions.calculate { (routeResponse, routeError) in
guard let routeResponse = routeResponse else {
if let routeError = routeError {
print(routeError)
}
return
}
self.mapView.removeOverlays(self.mapView.overlays)
let route = routeResponse.routes[0]
self.mapView.add(route.polyline, level: .aboveRoads)
}
}

Use of unresolved identifier 'objects'

How to define objects in the code and of which type?
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate=UIApplication.sharedApplication().delegate as! AppDelegate
let context=appDelegate.managedObjectContext
let request=NSFetchRequest(entityName:lineEntityName)
do{
let objects = try context.executeFetchRequest(request)
}
catch let error as NSError {
print(error)
}
if let objectList=objects
{
for oneObject in objectList
{
let lineNum=oneObject.valueForKey(lineNumberKey) as integerValue
let lineText=oneObject.valueForKey(lineTextKey) as String
let lineField=lineFields(lineNum)
textField.text=lineText
}
}
else
{
print("There was an Error")
}
let app=UIApplication.sharedApplication()
NSNotificationCenter.defaultCenter().addObserver(self, selector:"applicationWillResignActiveNotification", name: UIApplicationWillResignActiveNotification, object: app)
// Do any additional setup after loading the view, typically from a nib.
}
The recommended way is to put all good code in the do clause which solves the problem.
And executeFetchRequest returns a non-optional array so the optional binding can be omitted.
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context = appDelegate.managedObjectContext
let request = NSFetchRequest(entityName:lineEntityName)
do {
let objects = try context.executeFetchRequest(request)
for oneObject in objects
{
let lineNum = oneObject.valueForKey(lineNumberKey) as integerValue
let lineText = oneObject.valueForKey(lineTextKey) as String
let lineField = lineFields(lineNum)
textField.text = lineText
}
let app = UIApplication.sharedApplication()
NSNotificationCenter.defaultCenter().addObserver(self, selector:"applicationWillResignActiveNotification", name: UIApplicationWillResignActiveNotification, object: app)
// Do any additional setup after loading the view, typically from a nib.
}
catch let error as NSError {
print(error)
}
}

Blank/Black view when attempting to set delegate/data source

I am attempting to load a view from a .xib file as per this question:
Assign xib to the UIView in Swift
My setup is as follows:
StripView.xib — the .xib file from which I am loading the view, contains a single UIView
StripView.swift — the 'owner' of the UIView in StripView.xib, contains references/IBOutlets for each component in StripView.xib
StripViewController.swift — The view controller, which loads an instance of StripView and handles most of the logic/data source/delegate stuff.
This all worked fine in Xcode 6 Beta 4, however, upgrading to Xcode 6 Beta 5 (the latest) breaks. On app launch, I simply get a blank, black screen. All other parts of the app seem to work fine. This bug only occurs when I attempt to set the delegate or data source of a UIPickerView (owned by StripView) to the StripViewController.
Code snippet:
class StripViewController: SWRevealViewController, RSColorPickerViewDelegate, UIPickerViewDataSource, UIPickerViewDelegate, BLEDelegate, UIActionSheetDelegate, UITextFieldDelegate {
var stripView: StripView!
var colorPicker: RSColorPickerView!
var connectBtn:UIButton!
var connectionSpinner:UIActivityIndicatorView!
var tapRecognizer:UITapGestureRecognizer!
init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// use UIView extension as per https://stackoverflow.com/questions/24370061/assign-xib-to-the-uiview-in-swift
stripView = UIView.loadFromNibNamed("StripView") as StripView
self.view.addSubview(stripView)
// nav bar setup //
self.title = "Strip \(self.tabBarController.selectedIndex+1)"
let leftNav:UIView = UIView(frame: CGRectMake(0,0,100,40))
self.connectBtn = UIButton(frame: CGRectMake(0,0,95,40))
connectBtn.frame = CGRectMake(0,0,connectBtn.bounds.size.width,connectBtn.bounds.size.height)
connectBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
connectBtn.setTitle("Connect", forState: UIControlState.Normal)
connectBtn.setTitleColor(UIColor(red: 0.0, green: 122.0/255.0, blue: 1.0, alpha: 1.0), forState: UIControlState.Normal)
connectBtn.addTarget(self, action: "connectButtonPressed:", forControlEvents: UIControlEvents.TouchDown)
leftNav.addSubview(connectBtn)
self.connectionSpinner = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
connectionSpinner.frame = CGRectMake(connectBtn.frame.minX + connectBtn.bounds.size.width, connectBtn.frame.minY + 10, connectionSpinner.bounds.size.width, connectionSpinner.bounds.size.height)
connectionSpinner.hidesWhenStopped = true
leftNav.addSubview(connectionSpinner)
let leftNavItem:UIBarButtonItem = UIBarButtonItem(customView: leftNav)
self.navigationItem.leftBarButtonItem = leftNavItem
// set up color picker
colorPicker = RSColorPickerView(frame: CGRectMake(20, 78, 160, 160))
self.view.addSubview(colorPicker)
colorPicker.delegate = self
// set up mode picker
// THESE APPEAR TO BE THE OFFENDING LINES —
// COMMENTING THEM OUT DISPLAYS THE VIEW AS EXPECTED
self.stripView.modePicker.dataSource = self;
self.stripView.modePicker.delegate = self;
// set up notifications
NSNotificationCenter.defaultCenter().addObserver(self, selector: "colorFieldDidChange:", name: "ColorFieldDidChangeNotification", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
// set up UI and populate fields
self.stripView.setAnimSpeed()
// set up BLE
BLEManager.instance.ble.delegate = self
}
[...]
Once more, the offending lines appear to be:
self.stripView.modePicker.dataSource = self;
self.stripView.modePicker.delegate = self;
If I comment them out, all else displays as normal. I even attempted moving the delegate/data source into StripView.swift (not StripViewController), but I see the same result.
Here's the part of StripViewController that implements UIPickerViewDataSource and UIPickerViewDelegate methods:
func numberOfComponentsInPickerView(pickerView: UIPickerView!) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int {
return DataModel.instance.ModeNames.count
}
func pickerView(pickerView: UIPickerView!, titleForRow row: Int, forComponent component: Int) -> String! {
return DataModel.instance.ModeNames[row]
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) {
// send mode to arduino
println("--- sending mode select command ---")
var buf:[UInt8] = [0x00, 0x00, 0x00, 0x00]
buf[0] = Modes.instance.SET_MODE
buf[1] = UInt8(DataModel.instance.ModeOpcodes[DataModel.instance.ModeNames[row]]!)
let data:NSData = NSData(bytes: buf, length: 4)
BLEManager.instance.ble.write(data)
}
Did something change in the way the Swift language handles delegates/data sources, or view loading from a XIB?
EDIT:
I've narrowed down the problem to the DataModel singleton I'm using as a datasource. That code (DataModel.swift) looks like so, implementing a basic singleton pattern as per https://github.com/hpique/SwiftSingleton :
class DataModel {
// setup singleton
class var instance: DataModel {
struct Static {
static let instance : DataModel = DataModel()
}
return Static.instance
}
// modes
// eventually may replace this with a more flexible data structure
// for now, we just need names
let ModeNames: Array<String> = ["Light All", "Rainbow"]
let ModeOpcodes: Dictionary<String, UInt8> = [DataModel.instance.ModeNames[0]: Modes.instance.LIGHT_ALL, DataModel.instance.ModeNames[1]: Modes.instance.RAINBOW];
}
Replacing instances of this with a variable defined in StripViewController results in things working fine. Something about it being a singleton seems to be throwing things off. Thoughts? Perhaps the singleton is not being instantiated correctly?
One thing easily overlooked is connecting the data source and delegate to the view controller itself. In addition to ctrl dragging an outlet, you need to ctrl drag the data source and delegate from the connections inspector to the small view controller icon on top of the view in the storyboard.

Resources