xcode / swift receiving user data through a form - swift

I've been designing an app where the user needs to be able to send me the value of certain variables within the app. I originally planned to use a simple mail setup where they fill out a form and the game data is automatically filled out in the email.
Is there any way a user can click a button, and send me the values of variables within the app without the user specifically seeing or being able to modify the variables?
The user consents and realizes what they are doing to. I've been looking at firebase and seeing if there's anything there which can help me. Any ideas would be greatly appreciated.

Is there any way a user can click a button, and send me the values of
variables within the app without the user specifically seeing or being
able to modify the variables?
Yes. Add a UIButton to your storyboard and create a IBAction for it. Whenever the button gets tapped the IBAction gets called. In this case the IBAction is named didTapbutton. See the code below:
import UIKit
class ViewController: UIViewController {
var secretName = "Bond"
var secretNumber = 007
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func didTapButton(_ sender: Any) {
mail(to: secretName, secretNumber: secretNumber)
}
func mail(to secretName: String, secretNumber: Int) {
print("hello \(secretName + secretNumber)")
}
}
didTapButton uses the local variables secretName and secretNumber "within the app" without the user seeing the values.

Related

How do I offer a "sent action" from a custom class?

I'm developing a custom class in Swift based on NSObject. It's a statusMenu icon/menu helper. When I receive an event for the icon being clicked in my custom class, I want to pass this on in the same way an NSButton allows to create an IBAction to respond to the user clicking the button.
How do I do this?
Code:
I'm registering a selector in my class to listen to clicks:
statusItem.action = #selector(statusBarIconClicked)
The selector receiving this:
#objc func statusBarIconClicked(sender: AnyObject) {
print("clicked clicked!!")
// pass sent action on through a new sent action... how?
}
I want this to be linkable to the user in the same way a button can lead to this:
#IBAction func myClassSaysMenuWasClicked(_ sender: Any) {
// Reacting to that
}
Googled for a good while and found: nothing.
I take it that you're asking about this sort of thing, displayed in the Connections inspector (this is iOS, not macOS, but it's the same idea):
The question would then be: when the user selects an instance of my class in the nib editor in Xcode, I'd like those Sent Events to appear in the Connections inspector so that the user can hook up one of them and use the target-action architecture.
You can do this only if your class is a Control subclass. Thus, for example, in iOS, a custom UIControl subclass displays those sent events in Interface Builder.
If you can't do that, then the programmer won't be able to configure your target-action in Interface Builder. You can certainly implement a target–action architecture, but the programmer will have to set the target and action in code. (You could do half a job of it by making the target an outlet, of course.)
I worked around the comment above and googled further. I found the solution being to change from NSObject to NSController in this line:
class StatusMenuController: NSControl, NSMenuDelegate {
And run this command when I want to trigger the sent action:
if let theAction = self.action { NSApp.sendAction(theAction, to: self.target, from: self) }
The if-command of course checking so that an action is actually set before trying to use it.
I found no ways during my research to add any further sent actions. The way to go here seems to be delegates.

How to programmatically show a window/view controller in Swift 4 for macOS application

I'm trying to programmatically show a window in my macOS application. The reason I want to do it programmatically is because the user clicks a Login button and the resulting function depends on the success of the login. If it was successful, the window is shown; otherwise, it is not.
Here is a screenshot of my Xcode window:
Here's what I'm trying in the code (Alert is a class I created to make showing NSAlert dialogs easier):
#IBAction func btnLogin_Click(_ sender: Any) {
let email = txtEmail.stringValue
if(email.isEmpty) {
Alert.show(parent: view.window!, message: "Email is required.")
return
}
let password = txtPassword.stringValue
if(password.isEmpty) {
Alert.show(parent: view.window!, message: "Password is required.")
return
}
// this does not work, even though I gave the window and view controllers
// both identifiers in the storyboard
self.storyboard?.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("wcStores"))
}
Apple's documentation for NSStoryboard.SceneIdentifier is pretty much nonexistent, and other methods I've seen seem to pertain to earlier versions of Swift.
What am I doing wrong?
Alright, so this is not what I originally was trying to do, but this way is much better, and what I was really looking for.
let vcStores = self.storyboard?.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("vcStores"))
as! NSViewController
self.view.window?.contentViewController = vcStores
This will just replace the window's contents with the contents in the view vcStores as defined in Interface Builder.
This video also helped, albeit for iOS and Swift 3. I was trying to create a new NSWindow at first because I'm so used to doing desktop development in Java Swing or C# Windows Forms. But I love how easy it is to just switch out the window contents like this.

Xcode 7.2.1 Making a Reset Button using a Button with Swift

I am trying to make a reset button for my app that will reset the UI to the original state. I have made a UIButton and linked it to the ViewController, but I have no idea where to go from here. I tried using the following code:
#IBAction func resetToOriginalState(sender: UIButton) {
self.resetToOriginalState (sender: UIButton)
}
It gave me the following error:
Editor placeholder in source file
Sorry if there may be an obvious answer, but I am very new to Swift and Xcode.
Is there any other way to create a reset button?
The error:
Editor placeholder in source file
Is because you are calling a function with the UIButton Class name instead of the actual button.
#IBAction func resetToOriginalState(sender: UIButton {
// this line is wrong, you shouldn't have UIButton in here
self.resetToOriginalState (sender: UIButton)
// the line should read
self.resetToOriginalState (sender: sender)
}
This way, you are passing the actual button into the function that was passed to resetToOriginalState
Seems you have too IBAction for the same button, check how many time you have #IBAction func resetToOriginalState(sender: UIButton) in your code and remove the references from the references Interface list to clean it, should there be only one :
It depends what is in the scene and what do you need to reload. As far is I know you can't really segue a ViewController to itself, but here are few options:
Try to add loadView() when the button is pressed
Duplicate the view controller, and segue between the two. (might be risky and create more work)
Reset your variables to their initial state when the button is pressed
You should give us more detail because this is implementation specific.
Nevertheless, it's not very clean, but depending on the architecture of your code, you might be able to generate a new instance of your view controller, destroy the current one, and present the new one.

change UIButtonOutlet Image from AppDelegate

I would like to let the user know when new content is available via the image of a button. Take snapchat for instance: the user is aware of new snaps because the left button turns red (on the mainView). I would like to do the same.
I already processed the notification in the background in
didReceiveRemoteNotification. Thanks to this post, I was able to awake the app in the background when a new APN arrives.
Now I would like to update the image of a button straight from applicationWillEnterForeground. This is the only way that comes to my mind as the view is already loaded when the user clicks on the app (not the banner or the notification center).
Any help would be greatly appreciated. Thank you.
If anybody ever comes across the same problem...
Trying to interact directly with a ViewController from the AppDelegate was obviously a terrible idea. Instead I came across this post that tells me how to know when a ViewController enters the foreground. Here is #nsgulliver answer:
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector:"doYourStuff", name:
UIApplicationWillEnterForegroundNotification, object: nil)
}
func doYourStuff(){
// your code
}
Then remove the observer:
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}

Segue following a change in criteria from a local notification in Swift

I have created a local notification in Swift which gives the option to end a current game without having to go back in to the app. That's all fine and works as it should. The issue I'm having is that if the user does this, I don't want them to go back to the Game view controller if that happens to be the last view that was open when the app entered the background. I would like them to go back to the app's Home view controller instead.
I expected to be able to add a perform segue to my Game view controller in the following way, should the criteria match. I tried adding it to viewDidAppear(), but it didn't work:
override func viewDidAppear(animated: Bool) {
if isThereACurrentGame() == false {
performSegueWithIdentifier("unwindToHomeScreen", sender: self)
}
}
Is this something to do with viewDidAppear() not being called when the app comes back to the foreground? If so, what might an alternative be?
P.S. My isThereACurrentGame() function works as it should, as does the performSegueWithIdentifier elsewhere in the view controller, so these aren't the cause of the problem.