change to another screen after login is successful - swift

The use case of the app I am developing is I will have login view at the initial. When user logs in with valid credentials, the user should see another view saying welcome user. I am totally beginner and I don't know much more about xcode. I see the screen navigation from storyboard but I have already done many things in xib.
Here is what I have done
SafariExtensionViewController.swift
import SafariServices
class SafariExtensionViewController: SFSafariExtensionViewController {
#IBOutlet weak var passwordMessage: NSTextField!
#IBOutlet weak var emailMessage: NSTextField!
#IBOutlet weak var message: NSTextField!
#IBOutlet weak var email: NSTextField!
#IBOutlet weak var password: NSSecureTextField!
static let shared = SafariExtensionViewController()
override func viewDidLoad() {
self.preferredContentSize = NSSize(width: 300, height: 250)
message.stringValue = ""
emailMessage.stringValue = ""
passwordMessage.stringValue = ""
}
#IBAction func userLogin(_ sender: Any) {
let providedEmailAddress = email.stringValue
let providedPassword = password.stringValue
let isEmailAddressValid = isValidEmailAddress(emailAddressString: providedEmailAddress)
self.message.stringValue = ""
emailMessage.stringValue = ""
passwordMessage.stringValue = ""
if isEmailAddressValid && providedPassword.count > 0 {
// api call is done here
// when success should show another screen
} else {
emailMessage.textColor = NSColor.red
emailMessage.stringValue = "Invalid Email"
}
}
}
here is the screenshot of xib.
Technology used
swift 4
xcode 9
not IOS its mainly for app extension
UPDATE
I am not using storyboard and also it's not IOS. I am using xib and from macos project I am trying to develop app extension which will be shown in browser as an extension.

A lot of time left from question posted, but it can be helpful for others as me (I'm porting safari legacy extension to safari app extension) and find the way with use of NSTabView with tabless style:
The use is:
Ensure to add NSObject in your storyboard from the Library:
And connect with the tabview from Outlet:
I'm rather newbie in Cocoa and Swift and if anyone knows more beautiful solution for routing, please share it with others!

Related

White blank screen is displayed on the simulator when I run my Swift app on xcode

I'm just learning Swift, and whenever I test my app, only a white blank screen is displayed on the simulator, however, when I close Xcode, the app loads up on the simulator and it works fine, does anyone know what's the reason for this?
Thank you very much in advance!
screenshot before closing xcode:
click to see
screenshot after closing xcode:
click to see
the code I used:
import UIKit
import SwiftUI
class ViewController: UIViewController {
#IBOutlet weak var priceTxt:UITextField!
#IBOutlet weak var SalesTaxTxt:UITextField!
#IBOutlet weak var totalPriceLbl:UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func calculateTotalPrice(_ sender: Any) {
let price = Double(priceTxt.text!)!
let salesTax = Double(SalesTaxTxt.text!)!
let totalSalesTax = price * salesTax
let totalPrice = price + totalSalesTax
totalPriceLbl.text = "$\(totalPrice)"
}
}

Enabling and disabling buttons in xcode

For a given simple audio app with a few buttons:
The button references inside ViewController is:
#IBOutlet weak var recordAudioButton: UIButton!
#IBOutlet weak var playAudioButton: UIButton!
#IBOutlet weak var processAudioButton: UIButton!
But where are those button names and references inside the xcode gui? Notice below that the Allow Recording button is highlighted: but there is no mention of recordAudioButton as a button name:
I want to modify the enabling/disabling logic of a different button that does not have a reference yet.. but can not see how/where to do that . The dialog does not show a way to view/change the button references. So where is the place to do that?
See in Referencing Outlets Section for each button.
You can set disable after buttons setup
#IBOutlet weak var recordAudioButton: UIButton! {
didSet { recordAudioButton.isEnabled = false }
}
#IBOutlet weak var playAudioButton: UIButton! {
didSet { playAudioButton.isEnabled = false }
}
#IBOutlet weak var processAudioButton: UIButton! {
didSet { processAudioButton.isEnabled = false }
}
Then in viewDidLoad check for permission
AVAudioSession.sharedInstance().requestRecordPermission() { [unowned self] allowed in
DispatchQueue.main.async {
self.recordAudioButton.isEnabled = allowed
self.playAudioButton.isEnabled = allowed
self.processAudioButton.isEnabled = allowed
}
}
Then your code
#IBAction func askForPermissions() {
recordingSession = AVAudioSession.sharedInstance()
do {
try recordingSession.setCategory(.playAndRecord, mode: .default)
try recordingSession.setActive(true)
recordingSession.requestRecordPermission() { [unowned self] allowed in
// UI related work has to be executed on main thread(queue)
DispatchQueue.main.async {
self.recordAudioButton.isEnabled = allowed
self.playAudioButton.isEnabled = allowed
self.processAudioButton.isEnabled = allowed
}
}
} catch let error {
presentError(withMessage: error.localizedDescription)
}
}
You just defined the button as an outlet. So it does not appear on the Touch Up Inside, it appears at outlets area. But you connect your other button to an action function, this button appears on the Touch Up Inside.
Given the starting point / hint from #Picode here is what I was missing to get a new UIButton reference. A Medium article helped pave the way https://medium.com/#GanChau/outlet-vs-action-connections-in-xcode-b5331fb233a1 . In particular we need to have both an Editor and the Visual Designer showing:
So on my project now I control-clicked on the new button Run DSP and the context menu shows up:
Now select New Referencing Outlet and connect it to the ViewController code:
I typed in dspJsButton for the Name and we get the following code generated:
#IBOutlet weak var dspJsButton: UIButton!

Just start HelloWorld display in MacOS application development [duplicate]

This question already has answers here:
(NSMenuItem): missing setter or instance variable
(3 answers)
Closed 4 years ago.
Tutorial for Hello World
I tried using the tutorial, link described above which was going until the execution but when i use the button click to display the name it show some error
Failed to connect (sayButtonClicked) outlet from
(HelloWorld.ViewController) to (NSButton): missing setter or instance
variable
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var nameField: NSTextField!
#IBOutlet weak var helloLabel: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
#IBAction func sayButtonClicked(_ sender: Any) {
var name = nameField.stringValue
if name.isEmpty{
name = "World"
}
let greeting = "Hello\(name)!"
helloLabel.stringValue = greeting
}
}
It sounds like you have an outlet connection in your storyboard named "sayButtonClicked" but "sayButtonClicked" is an IBAction, not an outlet. Try doing the following:
Delete that "sayButtonClicked" outlet from your storyboard.
Open your storyboard in the editor and the source-code for the view controller in an "assistant editor"
Control-drag from the dot next to your IBAction in your code onto the button in your storyboard. This will connect the action to the button. You may need to select "touch up inside" as the event you want to trigger the action.

Cocoa - PDFView/ThumbnailView dragging

I have a PDFView and a PDFThumbnailView and implemented it this way:
class PDFViewController: NSViewController {
#IBOutlet weak var pdfView: PDFView!
#IBOutlet weak var pdfThumbnailView: PDFThumbnailView!
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
let doc = PDFDocument(data: NSData(contentsOfFile: "file.pdf")!)
pdfView.setDocument(doc)
pdfView.setAllowsDragging(true)
pdfThumbnailView.setPDFView(pdfView)
pdfThumbnailView.setAllowsDragging(true)
}
}
Since the documentation says:
Sets whether users can drag thumbnails within the thumbnail view; that
is, re-order pages in the document.
I thought this would do it, but it isn't doing anything. I can't drag and drop and so reorder the document.
Connect pdfThumbnailView and pdfView before setting the document, in the xib or in code.

what to recast as an NSSplitViewItem

I am trying to self-learn OSX application development so I can make up all of my own bad habits 8).
Probably extraneous information
I have a trial app that works successfully - it resizes itself based on input from the user via a slider.
The key piece of code that does this is in one View controller ...
class JunkViewController2: NSViewController {
var myY: CGFloat!
#IBOutlet weak var mySlider: NSSlider!
#IBOutlet weak var myView: NSView!
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
self.preferredContentSize = NSMakeSize(self.view.frame.width, 83)
}
#IBAction func mySlider(sender: NSSlider) {
let mySplitViewController = self.childViewControllers[0] as! JunkSplitViewController
switch mySlider.intValue {
case 3:
myY = 140.0
mySplitViewController.splitViewItems[2].collapsed = false
mySplitViewController.splitViewItems[1].collapsed = false
mySplitViewController.showSubview(2)
mySplitViewController.showSubview(1)
mySplitViewController.showSubview(0)
case 2:
myY = 110.0
mySplitViewController.splitViewItems[2].collapsed = true
mySplitViewController.splitViewItems[1].collapsed = false
mySplitViewController.hideSubview(2)
mySplitViewController.showSubview(1)
mySplitViewController.showSubview(0)
default:
myY = 80.0
mySplitViewController.splitViewItems[2].collapsed = true
mySplitViewController.splitViewItems[1].collapsed = true
mySplitViewController.hideSubview(2)
mySplitViewController.hideSubview(1)
mySplitViewController.showSubview(0)
}
mySplitViewController.preferredContentSize = NSMakeSize(self.view.frame.width, myY - 50 + 3)
self.preferredContentSize = NSMakeSize(self.view.frame.width, myY + 3)
}
}
More pertinent information
In what is working, above, on the story board I have three duplicate ViewControllers connected to a SplitView controller. I do a bunch of what feels like belts and suspenders work to make sure that everything gets resized properly - but the key part (I think) is the .collapsed property.
I am now trying to accomplish the same thing, using a completely different method - dynamically adding / removing split view items. This should allow me to have only one of the small ViewControllers on my story board, and then instantiate it as needed.
Following that idea, here is my SplitViewController ...
class JunkSplitViewController: NSSplitViewController {
#IBOutlet weak var mySplitView: NSSplitView!
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
//mySplitView.adjustSubviews()
}
func makeChild() -> SmallViewController {
let mySmallGroup = NSStoryboard(name: "Main", bundle: nil).instantiateControllerWithIdentifier("smallVwCtl")
self.addSplitViewItem(mySmallGroup as! NSSplitViewItem)
return mySmallGroup as! SmallViewController
}
}
The main view controller invokes the makeChild function.
class JunkViewController: NSViewController {
#IBOutlet weak var mySlider: NSSlider!
#IBOutlet weak var myView: NSView!
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
self.preferredContentSize = NSMakeSize(self.view.frame.width, 83)
}
#IBAction func mySlider(sender: NSSlider) {
let mySplitViewController = self.childViewControllers[0] as! JunkSplitViewController
while mySlider.intValue.toIntMax() > mySplitViewController.splitViewItems.count.toIntMax() {
mySplitViewController.makeChild()
}
while mySlider.intValue.toIntMax() < mySplitViewController.splitViewItems.count.toIntMax(){
mySplitViewController.splitViewItems.removeLast()
}
}
}
I get an error at the self.addSplitViewItem(mySmallGroup as! NSSplitViewItem) line of JunkSplitViewController ... "Could not cast value of type Scratch2.SmallViewController to NSSplitViewItem"
I've tried a handful of combinations (forcing mySmallGroup, 'self.addSplitViewItem(mySmallGroup as! SmallViewController)`, etc.) Everything leads to a similar error, either at compile or run time.
I cannot find any documentation on SplitViewItem.
So the question - what will work as input to addSplitViewItem and still successfully connect a new instance of SmallViewController?
And gratefully accept any comments/feedback on the methodology
I hate it when I find my answer minutes after posting a question ...
Based on info I found here ...
func makeChild() -> SmallViewController {
let mySmallGroup = NSStoryboard(name: "Main", bundle: nil).instantiateControllerWithIdentifier("smallVwCtl") as! SmallViewController
self.addSplitViewItem(NSSplitViewItem(viewController: mySmallGroup))
return mySmallGroup
}
... but I'd still like to hear any feedback on methodology. Thanks.