Passing data forward to destination VC (with framework) in Swift? - xcode

I'm writing an application that takes data from a QR code scanner. I am just implementing the basics, and have a second view controller that is triggered when a new QR code is detected. The following code is in a custom view controller from RSBarcodes and implemented using CocoaPods.
It won't compile with the error
"Use of undeclared type SecondViewController".
I tried making my SecondViewController public, restarting XCode, and nothing has worked. Any help is appreciated. Thank you!
override public func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let destinationVC = segue.destinationViewController as! SecondViewController
destinationVC.label = "test"
}
SOLUTION:
Added to "Copy Bundle Resources" and then my VC was immediately recognized by the compiler.

SOLUTION:
Added to "Copy Bundle Resources" and then my VC was immediately recognized by the compiler.

First you have to verify which segue you're pushing to by checking the segue identifier name. Then you have to check if you can even create the destinationVC variable, and then if you can unwrap it using '?' instead of '!'.
override public func prepareForSegue(segue: UIStoryboardSegue, sender:AnyObject?) {
if segue.identifier == "nameOfMySegue" {
if let destinationVC = segue.destinationViewController as? SecondViewController {
destinationVC.label = "test"
}
}
}

Related

Cannot convert value of type 'NSStoryboardSegue.Identifier?' to expected argument type 'String'

Im using the following code to show a view controller,im identifying the segue using the identifier property.This code works fine in swift3 but when updating to swift4 I get the following error
Cannot convert value of type 'NSStoryboardSegue.Identifier?' to expected argument type 'String'
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if (segue.identifier == "segue") {
//get a reference to the destination view controller
let destinationVC:ProgressView = segue.destinationController as! ProgressView
//set properties on the destination view controller
destinationVC.fileArray=fileArray
destinationVC.croptype=croptype
destinationVC.outdir=outdir
destinationVC.fileformat=fileformat
destinationVC.tflag=tflag
if(resize==true)
{
destinationVC.resize=true
destinationVC.rwidth=rwidth
destinationVC.rheight=rheight
destinationVC.preserve_aspect_ratio=preserve_aspect_ratio
}
}
}
Please advice
In Swift 4 the type of the segue identifier has been changed to NSStoryboardSegue.Identifier
Two solutions
Compare the rawValue – and safely unwrap the identifier
if let identifier = segue.identifier, identifier.rawValue == "segue" { ...
(recommended) Create an extension
extension NSStoryboardSegue.Identifier {
static let segue = NSStoryboardSegue.Identifier("segue")
}
and compare
if let identifier = segue.identifier, identifier == .segue { ...

Pass data with segue form UITabBarItem not working

I want to pass data from one UIView to another UIView in order to go to the web site which will be different according to UITabBarItem that a user chooses. How can I do it?
func pathButton(dcPathButton: DCPathButton!, clickItemButtonAtIndex itemButtonIndex: UInt) {
switch itemButtonIndex {
case 0:
// working but can’t send data with it
self.performSegueWithIdentifier("goto", sender: self)
// not working as function is not trigger
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "goto" {
let vc = segue.destinationViewController as! WebMainViewController
vc.goURL = "http://google.com“
dcPathButton.delegate = self
println(“go to http//google.com”)
}
case 1:
println(“go to http://apple.com”)
case 2:
println(“go to http://imbd.com”)
case 3:
println(“go to http://facebook.com”)
default:
println(“go to http://cnn.com”)
}
Have you tried
func pathButton(dcPathButton: DCPathButton!, clickItemButtonAtIndex itemButtonIndex: UInt) {
switch itemButtonIndex {
case 0:
self.performSegueWithIdentifier("goto", sender: self)
// plus other cases
}
and then in a different section of your class you implement:
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "goto" {
let vc = segue.destinationViewController as! WebMainViewController
vc.goURL = "http://google.com“
}
Obviously make sure that your segue is hooked up and has "goto" set as an identifier.
Perhaps you could have some logic in prepareForSegue that sets vc.goURL instead of the switch statement that you currently have? For example, the user selects a particular value, you save that value to a variable and then when they click on a button to start the segue you check the value of that variable and set vc.goURL accordingly?

Why am I receiving these errors when trying to pass a variable on a segue in swift?

I am trying to build upon answer which I was given here. What I am trying to is very simple - I want a text field which you can enter text into. You press the go button and it takes you to a new view and replaces the text on a label on that page with whatever the user entered in the box. The is the code I am using on the first page.
import UIKit
class ViewController: UIViewController {
#IBOutlet var entry: UITextField!
let dictionary = entry.text // Line 7 ERROR
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.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "viewTwo"
{
if let destinationVC = segue.destinationViewController as? viewTwo{
destinationVC.dictionary = self.dictionary // Line 24 ERROR
}
}
}
#IBAction func goToViewTwo(sender: AnyObject) {
performSegueWithIdentifier("viewTwo", sender: self)
}
}
I am only including the code from the first view because i know the code from the second view is working.
I didn't encounter an error until I tried to use the text field - before when I just had a pre-choses text to transfer over it worked. Before, instead of having let dictionary = entry.text I had let dictionary = "foo" and it worked.
So my question is exactly the same thing but have a text field instead of pre-chosen text - what I really want to know is why my code didn't work before.
The errors I got were on line 7 (I have labeled the lines above which had the errors) - 'ViewController.Type' does not have member names 'entry' and there was also an error on line 24 but I suspect this is related to this error and will be fixed if this error is also fixed. Just incase though, the error on line 24 was: 'ViewController.Type' does not have member names 'dictionary'
Thank you.
You should set the dictionary to var dictionary = "" in the declaration. You use var instead of let here, so that you can change the value of the dictionary later.
Then inside your #IBAction func goToViewTwo(sender: AnyObject){} method, you set the self.dictionary = entry.text
#IBAction func goToViewTwo(sender: AnyObject) {
dictionary = entry.text
performSegueWithIdentifier("viewTwo", sender: self)
}
Alternatively, you can just do the following inside prepareForSegue() method.
This way, you dont need to declare a dictionary to hold the text value of your UITextField, you can just pass the text value from your entry to the second view controller's dictionary variable.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "viewTwo"
{
if let destinationVC = segue.destinationViewController as? viewTwo{
destinationVC.dictionary = self.entry.text
}
}
}
A dictionary is not constant, so declare it as lazy var, not let:
lazy var dictionary: String {
return entry.text
}()

(NSMenuItem): missing setter or instance variable

I am encountering a strange error:
2015-04-02 12:20:14.642 test[21167:257788] Failed to connect
(testApp) outlet from (test.AppDelegate) to (NSMenuItem): missing
setter or instance variable
inserted id: 122
I occured when a added a menuItem to a menu and connected a function to it.
I do not know what the Problem is. The app works fine but i don't think it is a smart idea to ignore the error.
What is meant by setter or instance variable? Why is it needed?
UPDATE: Here is the relevant code:
import Cocoa
import Foundation
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var statusMenu: NSMenu!
let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-1)
func applicationDidFinishLaunching(aNotification: NSNotification) {
let icon = NSImage(named: "statusIcon")
statusItem.image = icon
statusItem.menu = statusMenu
// Time for constant repeat
NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "timerRepeat", userInfo: nil, repeats: true)
}
// Method to call the tracking core
func timerRepeat() {
//....
}
#IBAction func frontEnd(sender: NSMenuItem) {
var targetURL : String = NSBundle.mainBundle().resourcePath!
targetURL = targetURL + "/" + "front.app"
let workspace = NSWorkspace()
workspace.launchApplication(targetURL)
}
#IBAction func menuClicked(sender: NSMenuItem) {
NSApplication.sharedApplication().terminate(self)
}
}
You have a broken outlet in your xib file. Usually it happens when you set up an outlet to ivar or property which is later deleted or renamed not using Xcode's rename feature.
Also make sure that your custom view or view controller class is added to your target. (Project => Target Name => Build Phases => Compile Sources). It's possible that a file is in your project but not your target.
This happens because you at one point created an #IBOutlet for a storyboard element. You then later removed the code (reference) from your swift file.
I created an example where I create two extra #IBOutlets (I named them 'correctField' and 'incorrectField'- both are incorrect though) and connected them from my storyboard to my swift file.
I then removed the code from my swift file. This generates the log as shown in the following figure :
To remove this kind of log message, you can do the following:
Go to the 'storyboard' and select the storyboard elements you created connections (#IBOutlets) from.
Open the 'connection inspector' as showed in the figure below
Remove the Referencing Outlets which are incorrect (in my case it is the 'correctField' and 'incorrectField')
Done
This was done in xCode 11

Parse SDK 1.7.1 not working in Xcode 6.3

My code worked fine in Xcode 6.2. After the update to Xcode 6.3 I had some Nullabilty Errors.
I could solve these errors after I downloaded the Parse SDK 1.7.1. So I deleted the old Parse framework files in my project and pasted the new ones into it. Additional I convert my code to the latest swift syntax "Edit/Convert/latest swift syntax". Now I haven't problems with Nullabilty Errors but several others.
In my project I have a simple Tableviewcontroller with the following code:
import UIKit
class HaendlerTableViewController: PFQueryTableViewController {
// Initialise the PFQueryTable tableview
override init!(style: UITableViewStyle, className: String!) { //1. Falialbe initialize init/style:className:)' cannot override a non-failable initializer
super.init(style: style, className: className)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Configure the PFQueryTableView
self.parseClassName = "Haendler"
self.textKey = "name"
self.pullToRefreshEnabled = true
self.paginationEnabled = false
}
// Define the query that will provide the data for the table view
override func queryForTable() -> PFQuery! { //2. Ovverriding method with selector queryForTable has incompatitble typ () -> PFQuery
var query = PFQuery(className: "Haendler")
query.orderByAscending("name")
return query
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject) -> PFTableViewCell { //3. Ovverriding method with selector 'tableView:cellForRowAtindexPath:object:' has incompatible type '(UITableView, NSIndexPath, PFObject) -> PFTableViewCell
var cell = tableView.dequeueReusableCellWithIdentifier("HaendlerCell") as! HaendlerCell!
if cell == nil {
cell = HaendlerCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
}
// Extract values from the PFObject to display in the table cell
cell.haendlerName.text = object["name"] as! String!
var thumbnail = object["logo"] as! PFFile
var initialThumbnail = UIImage(named: "haendler")
cell.haendlerBild.image = initialThumbnail
cell.haendlerBild.file = thumbnail
cell.haendlerBild.loadInBackground()
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var detailScene = segue.destinationViewController as! HaendlerDetailViewController
// Pass the selected object to the destination view controller.
if let indexPath = self.tableView.indexPathForSelectedRow() {
let row = Int(indexPath.row)
detailScene.currentObject = objects[row] as? PFObject //4. Could not find an overload for 'subscript' that accepts the supplied agruments
}
}
}
I wrote the errors in a comment on the right side of the code and
below.
Falialbe initialize init/style:className:)' cannot override a non-failable initializer
Ovverriding method with selector queryForTable has incompatitble typ () -> PFQuery
Ovverriding method with selector 'tableView:cellForRowAtindexPath:object:' has incompatible type '(UITableView, NSIndexPath, PFObject) -> PFTableViewCell
Could not find an overload for 'subscript' that accepts the supplied agruments
I have the same errors when I make a new Swift project from the Parse Quickstart and add one Tableviewcontroller. In my old project was an objective-C bridging header which one I deleted because I had the oppurtunity to add the Parse SDK 1.7.1 directly in my Swift project.
Now I need help because I don't see what I have to change..
PS: Sorry for the mix of German and English code I'll adjust it once the project is running again
I had the same issue as I just updated Xcode to 6.3 about 20 minutes ago.
For your 2nd error, remove the '!' after 'PFQuery'. So it should now look like..
override func queryForTable() -> PFQuery {
This solved my problem in regards to that specific error.
I never used an init method as you did in your first error, but try removing it and see what you get. My PFQueryTableViewController works fine without it.
Had the same issues.
To solve the first initialise issue remove the '!' after 'override init'. Should look like this:
// Initialise the PFQueryTable tableview
override init(style: UITableViewStyle, className: String!) { //1. Falialbe initialize init/style:className:)' cannot override a non-failable initializer
super.init(style: style, className: className)
}
Do the same for the 2nd error after 'PFQuery'
override func queryForTable() -> PFQuery {
Hope its helpful. Since the latest update unwrapping elements usually needs to be revised for possible errors.

Resources