UserDefault in Xcode is not saving the text - xcode

This code won't save the text for same reason. How to fix it?
import UIKit
class ViewControllertextview: UIViewController {
#IBOutlet weak var text: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
_ = UserDefaults.standard
let value = UserDefaults.standard.string(forKey: "onekey")
if value != nil{
text.text = value
}
else {
text.text = "Here you can make Notes"
}
}
let defaults = Foundation.UserDefaults.standard
#IBAction func Sbutton(_ sender: Any) {
UserDefaults.standard.set(text.text, forKey: "onekey")
}
#IBAction func ggbutton(_ sender: Any) {
}
}

UserDefaults don't immediately write data to storage. You can try calling UserDefaults.standard.synchronize() to save immediately, right after UserDefaults.standard.set(..

Related

How to update a Status Item created by AppDelegate from NSViewController

I'm trying to create a Countdown Timer application that runs in the Menu Bar, with no window or dock icon. I've been building this off of mostly tutorials I find online and I know the code is kind of messy (I plan to clean up after it functions properly). The issue I'm running into. In the AppDelegate I create the StatusBar item with no issue, but I can't figure out how to update it from the viewController. It instead is creating a new StatusBar item.
//AppDelegate info
class AppDelegate: NSObject, NSApplicationDelegate
{
let item = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
let popover = NSPopover()
func applicationDidFinishLaunching(_ aNotification: Notification)
{
menuBarRefresh(self)
}
func menuBarRefresh(_ sender: Any?)
{
if let button = item.button
{
button.image = NSImage(named: NSImage.Name("2"))
//button.title = initialTime.stringValue
button.action = #selector(togglePopover(_:))
}
popover.contentViewController = TimerViewController.freshController()
}
#objc func togglePopover(_ sender: Any?)
{
if popover.isShown
{
closePopover(sender: sender)
}
else
{
showPopover(sender: sender)
}
}
func showPopover(sender: Any?)
{
if let button = item.button
{
popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
}
}
func closePopover(sender: Any?)
{
popover.performClose(sender)
}
//Controller code
import Cocoa
import AVFoundation
//Checking to ensure entered data is numeric
extension String
{
var isNumeric: Bool
{
let range = self.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted)
return (range == nil)
}
}
class TimerViewController: NSViewController
{
//Here's the texts fields for the user to enter content.
#IBOutlet var hourInput: NSTextField!
#IBOutlet var minuteInput: NSTextField!
#IBOutlet var secondInput: NSTextField!
//This is the label used to display the counter
#IBOutlet var initialTime: NSTextField!
//Here are the variables we're going to need
var hours = Int() //Place holder for the hours
var minutes = Int() //Place holder for the hours
var seconds = Int() //Place holder for the hours
var timer = Timer() //The timer we'll use later
var audioPlayer = AVAudioPlayer() //The audio player
var timeRemaining = Int() //Place holder for the total 'seconds' to be counted
var firstRun = Bool()
let item = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
override func viewDidLoad()
{
super.viewDidLoad()
getData() //Pull last saved time from Core Data and load it.
hourInput.stringValue = "\(hours)" //Loading the hours into the hours field
minuteInput.stringValue = "\(minutes)" //Loading the minutes into the minutes field
secondInput.stringValue = "\(seconds)" //Loading the seconds into the seconds field
initialTime.stringValue = "00:00:00" //Resetting the 'counter' to 0
firstRun = true
updateStatusBar(self)
//Here we load up the audio file for the 'done' chime. If not available we print the catch
do
{
let audioPath = Bundle.main.path(forResource: "Done", ofType: "m4a")
try audioPlayer = AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath!))
}
catch
{
print("No Joy")
}
/* if let button = item.button
{
button.image = NSImage(named: NSImage.Name("2"))
button.title = initialTime.stringValue
button.action = #selector(togglePopover(_:))
}
*/ }
}
// MARK: Storyboard instantiation
extension TimerViewController
{
static func freshController() -> TimerViewController
{
let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
let identifier = NSStoryboard.SceneIdentifier("TimerViewController")
guard let viewcontroller = storyboard.instantiateController(withIdentifier: identifier) as? TimerViewController
else
{
fatalError("Why can't I find TimerViewController? - Check Main.storyboard")
}
return viewcontroller
}
}
//Button actions follow
extension TimerViewController
{
#IBAction func clearButton(_ sender: Any)
{
clearFields()
timer.invalidate()
audioPlayer.stop()
}
#IBAction func pauseButton(_ sender: Any)
{
timer.invalidate()
}
#IBAction func quitButton(_ sender: Any)
{
exit(0)
}
#IBAction func startButton(_ sender: Any)
{
grabData()
setData()
timeRemaining = (hours*3600)+(minutes*60)+seconds
if timeRemaining <= 0
{
initialTime.stringValue = "Enter Time"
}
else
{
displayTime()
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.startCountDown), userInfo: nil, repeats: true)
clearFields()
updateStatusBar(self)
}
}
}
//MARK: Other Functions
extension TimerViewController
{
func displayTime()
{
let secondsDisplay = String(format: "%02d", (timeRemaining%60))
let minutesDisplay = String(format: "%02d", (timeRemaining%3600)/60)
initialTime.stringValue = "\(timeRemaining/3600):\(minutesDisplay):\(secondsDisplay)"
}
func grabData()
{
hours = hourInput.integerValue
minutes = minuteInput.integerValue
seconds = secondInput.integerValue
}
func clearFields()
{
hourInput.stringValue = ""
minuteInput.stringValue = ""
secondInput.stringValue = ""
initialTime.stringValue = "00:00:00"
}
func setData()
{
setHour()
setMinute()
setSecond()
}
func getData()
{
getHour()
getMinute()
getSecond()
}
#objc func showTimer(_ sender: Any?)
{
print("Are we here")
}
#objc func startCountDown()
{
timeRemaining -= 1
displayTime()
updateStatusBar(self)
print(timeRemaining)
if timeRemaining == 0
{
timer.invalidate()
audioPlayer.play()
}
}
/* func setNeedsStatusBarAppearanceUpdate()
{
button.image = NSImage(named: NSImage.Name("2"))
button.action = #selector(showTimer(_:))
}
*/
func updateStatusBar(_ sender: Any?)
{
if let button = item.button
{
button.image = NSImage(named: NSImage.Name("2"))
button.action = #selector(showTimer(_:))
button.title = initialTime.stringValue
}
//let menu = NSMenu()
//menu.addItem(NSMenuItem(title: "Clear Timer", action: #selector(AppDelegate.theDv2), keyEquivalent: "R"))
//menu.addItem(NSMenuItem(title: "Quit Timer", action: #selector(AppDelegate.quit), keyEquivalent: "Q"))
//item.menu = menu
}
}
//There's a bunch of CoreData stuff after here but I left that out. I'm just using CoreData mainly to learn how to and functional reason is to store and load the last used time
As it currently works, I get two StatusBar items instead of creating one with the AppDelegate then updating that one from the ViewController.
Yup... Id-10-t error here. Just had to declare 'item' outside the class and all is well. After getting some good sleep and time away from the computer I realized I was not declaring 'item' globally.

Swift 3D Touch Quick Action not loading requested url

I'm new to Swift, and trying my hands with UIWebView app that loads default url, with option to perform quick action and load a different url.
Problem is when I request the quick action url, code executes but the new url is not loading. So I'm missing something in the flow somewhere.
Here is the code:
import UIKit
import WebKit
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var webView: UIWebView!
override func loadView() {
super.loadView()
self.webView = UIWebView()
self.view = self.webView!
}
override func viewDidLoad() {
print("view did load")
super.viewDidLoad()
let url = NSURL(string: "google.com")
let req = NSURLRequest(URL:url!)
webView.loadRequest(req)
webView.delegate = self
}
func loadUrl2() {
loadView()
let url = NSURL(string: "example.com")
print(url)
let req = NSURLRequest(URL:url!)
self.webView!.loadRequest(req)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I was experimenting and added loadView to loadUrl2, as I was getting
fatal error: unexpectedly found nil while unwrapping an Optional value
before that.
Edited to Include loading secondary link:
Here are the changes and files you'll need to make to the App Delegate
enum ShortcutIdentifier: String {
case OpenNewLink
case OpenBetterLink
init?(fullIdentifier: String) {
guard let shortIdentifier = fullIdentifier.componentsSeparatedByString(".").last else {
return nil
}
self.init(rawValue: shortIdentifier)
}
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsAnnotationKey] as? UIApplicationShortcutItem {
handleShortcut(shortcutItem)
return false
}
return true
}
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
completionHandler(handleShortcut(shortcutItem))
}
private func handleShortcut(shortcutItem: UIApplicationShortcutItem) -> Bool {
let shortcutType = shortcutItem.type
guard let ShortcutIdentifier = ShortcutIdentifier(fullIdentifier: shortcutType) else {
return false
}
return selectLinkForIdentifier(ShortcutIdentifier)
}
private func selectLinkForIdentifier(identifier: ShortcutIdentifier) -> Bool {
guard let mainView = self.window?.rootViewController as? ViewController else {
return false
}
switch identifier {
case .OpenNewLink:
mainView.urlString = "http://www.bing.com"
mainView.loadWebView(mainView.urlString)
return true
case.OpenBetterLink:
mainView.urlString = "http://www.duckduckgo.com"
mainView.loadWebView(mainView.urlString)
return true
}
}
I also made changes in the MainVC
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var webView: UIWebView!
var urlString: String? = nil
override func viewDidLoad() {
super.viewDidLoad()
setUpWebView()
webView.delegate = self
view.addSubview(webView)
}
func setUpWebView() {
webView = UIWebView()
webView.frame = CGRectMake(0, 0, view.frame.width, view.frame.height)
loadWebView(urlString)
}
func loadWebView(var urlString: String?) {
if urlString == nil {
urlString = "http://www.google.com"
}
let url = NSURL(string: urlString!)
let req = NSURLRequest(URL:url!)
webView.loadRequest(req)
}
}
Be sure to add NSAppTransportSecurity dictionary to your .plist and add NSAllowsArbitraryLoads key set to YES.
I tested it and it should work for you.

How do I setup a sign in page using parse and swift in Xcode (error with 'signInBackgroundWithBlock')?

I'm trying to setup a sign in page using parse and swift in Xcode but I keep getting an error with 'signInBackgroundWithBlock' how do I make this work?
I keep receiving the message
Cannot invoke 'signUpInBackgroundWithBlock' with an argument list of
type ((Bool!, NSError!) -> Void)
so far this is what I have and I just have an error with that part.
import UIKit
import Parse
class EmailLogin: UIViewController, UITextFieldDelegate {
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var statusLabel: UILabel!
#IBOutlet weak var createAccountButton: UIButton!
#IBOutlet weak var passwordTextField: UITextField!
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
emailTextField.delegate = self;
passwordTextField.delegate = self;
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func createAccountButtonPressed(sender: AnyObject)
{
if verifyEmailDomain(self.emailTextField.text)
{
createAccount(self.emailTextField.text, password: self.passwordTextField.text)
}
else
{
//self.statusLabel.text = "Email domain is not valid.";
let alert = UIAlertView()
alert.title = "Invalid Email Domain"
alert.message = "Make sure you entered in your address correctly. If you did, ask your system about using PageMD! Thanks."
alert.addButtonWithTitle("Close")
alert.show()
}
}
func verifyEmailDomain(email: String) -> Bool
{
var isVerifiedDomain = false
let userDomain: String = (email.componentsSeparatedByString("#")).last!
//NSLog(userDomain)
let validDomainsFileLocation = NSBundle.mainBundle().pathForResource("ValidDomains", ofType: "txt")
var validDomainsFileContent = NSString(contentsOfFile: validDomainsFileLocation!, encoding: NSUTF8StringEncoding, error: nil)
//NSLog(validDomainsFileContent!)
let validDomains = validDomainsFileContent!.componentsSeparatedByString("\n")
for domain in validDomains
{
NSLog(domain as! NSString as String)
if userDomain == (domain as! NSString)
{
isVerifiedDomain = true
break
}
}
return isVerifiedDomain
}
func createAccount(email: String, password: String)
{
var newUser = PFUser()
newUser.username = email // We want the user to login only with their email.
newUser.email = email
newUser.password = password
//this where i get my error//
newUser.signUpInBackgroundWithBlock { (succeeded: Bool!, error: NSError!) -> Void in
if error == nil
{
// Account created successfully!
if succeeded == true
{
self.statusLabel.text = "Account created!"
}
}
else
{
if let errorField = error.userInfo
{
self.statusLabel.text = (errorField["error"] as NSString)
}
else
{
// No userInfo dictionary present
// Help from http://stackoverflow.com/questions/25381338/nsobject-anyobject-does-not-have-a-member-named-subscript-error-in-xcode
}
}
}
}
func textFieldShouldReturn(textField: UITextField) -> Bool
{
textField.resignFirstResponder()
return true;
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
If you are using swift 1.2 (Xcode 6.3) you need to call the function by:
newUser.signUpInBackgroundWithBlock({(succeeded:Bool, error:NSError?) -> Void in
})
And if you are using swift 1.1 (Xcode 6.1, 6.2) you need to call the function by:
newUser.signUpInBackgroundWithBlock({(succeded:Bool, error:NSError!) -> Void in
})
This is different because of the swift update 1.2 which has changes with using optionals.
Another way is to write it like this:
(Works in old and new swift)
newuser.signUpInBackgroundWithBlock { (succeded, error) -> Void in
}

Swift / Spring: SoundPlayer.play("string.wav") not working

I try to use the Spring Framework to play a sound when a button is touched.
import UIKit
class ViewController: UIViewController {
//TODO: max, mia, beide arrays und zufallsgenerator und happy day unten mit klick gleich wave
#IBAction func soundButton(sender: AnyObject) {
let mySound : String! = "refresh.wav"
SoundPlayer.play(mySound)
}
#IBOutlet weak var imageView: SpringImageView!
#IBAction func beideButton(sender: AnyObject) {
imageView.image = UIImage(named: "b1")
imageView.animation = "zoomIn"
imageView.animate()
}
#IBAction func maxButton(sender: AnyObject) {
imageView.image = UIImage(named: "max1")
imageView.animation = "slideLeft"
imageView.animate()
}
#IBAction func miaButton(sender: AnyObject) {
imageView.image = UIImage(named: "mia1")
imageView.animation = "slideRight"
imageView.animate()
}
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.
}
}
I get the following error: Cannot invoke 'play' with an argument list of type ('String')
I tried view things like as!, as String, as String!, as? String to unwrap or so but can not figure it out...
Here is the SoundPlayer class (Copyright (c) 2015 James Tang (j#jamztang.com):
import UIKit
import AudioToolbox
public class SoundPlayer: NSObject {
#IBInspectable var filename : String?
#IBInspectable var enabled : Bool = true
private struct Internal {
static var cache = [NSURL:SystemSoundID]()
}
public func playSound(soundFile:String) {
if !enabled {
return
}
if let url = NSBundle.mainBundle().URLForResource(soundFile, withExtension: nil) {
var soundID : SystemSoundID = Internal.cache[url] ?? 0
if soundID == 0 {
AudioServicesCreateSystemSoundID(url, &soundID)
Internal.cache[url] = soundID
}
AudioServicesPlaySystemSound(soundID)
} else {
println("Could not find sound file name `\(soundFile)`")
}
}
#IBAction public func play(sender: AnyObject?) {
if let filename = filename {
self.playSound(filename)
}
}
}
Judging by the code alone (I'm not familiar with Spring), what you need to do is create a SoundPlayer instance and call playSound on it (not play, which uses an internal filename for the sound to play instead of its argument), like this:
#IBAction func soundButton(sender: AnyObject) {
let mySound : String! = "refresh.wav"
let soundPlayer = SoundPlayer()
soundPlayer.playSound(mySound)
}

Swift: how to call NSSpeechRecognizer func

My speechRecognizer func doesn't seem to be called. I couldn't find anything in the documentation about calling this func.
Any idea what I might be doing wrong? Thanks in advance.
class ViewController: NSViewController, NSSpeechRecognizerDelegate {
let SR:NSSpeechRecognizer = NSSpeechRecognizer()
var commands = ["word","hello"]
override func viewDidLoad() {
super.viewDidLoad()
SR.commands = commands
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
#IBAction func Listen(sender: AnyObject) {
SR.startListening(); print("listening")
}
#IBAction func Stop(sender: AnyObject) {
SR.stopListening()
}
func speechRecognizer(sender: NSSpeechRecognizer,
didRecognizeCommand command: AnyObject?){
if (command as String == "word")
{
println("case word")
}
else if (command as String == "happy")
{
println("case happy")
}
}
}
Set the NSSpeechRecognizerDelegate to self:
SR.delegate = self

Resources