I have what I think should be a very simple operation. I just want to have an entry in a Firebase DB changed when I press a button. I already checked that there's nothing wrong with the button.
Here is my FireBase entry, by the way:
This code works fine in displaying text to the console (so, no problem with the button or connection, or variable, for that matter):
#IBAction func test(_ sender: Any) {
print("Username: \(requestUsername)")
}
My simple IBAction function gets a SIGABRT every time. I tried to look at other S.O. questions on the best way to update values, and to try to follow their suggestions, so I'm not sure if my firebase code is messed up, or something else. Right now, "ref" is declared inside the IBAction, but I've also tried declaring it globally, with the same result.
#IBAction func test(_ sender: Any) {
var ref = FIRDatabase.database().reference()
ref.child("Sell_Request").child(requestUsername).child("Request_Made").setValue("true")
}
Update:
For what it's worth, I'm able to get the correct Firebase entry with this code. I'm still not sure how to update specific fields. If anyone has any ideas, I would appreciate it.
ref.child("Sell_Request").queryOrdered(byChild: "name").queryEqual(toValue: requestUsername).observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot)
})
}
Related
I'm struggling with asynchronous code in Swift. I have to disable 2 buttons if there is no internet connection. I have 2 DispatchQueue.main.async calls in 2 different functions. 1 of them works, but the other one doesn't disable the button (the good thing is that you can click on the button and nothing happens). I am testing my code on my iPhone because the simulator does not run the SDK I am using properly.
All these functions look like this (this is the one at the end that does not work):
public func disableButton2(_ check: Bool) {
DispatchQueue.main.async{
self.button2.isEnabled = check
}
I have used this and it was working fine
DispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) { [weak self] in
guard let self = self else {
return
}
try this you will get the result.
A kind of more accurate approach, in order to explain "why asyncAfter works instead of just async" would be that DispatchQueue.main.asyncAfter would capture the thread in order to make the UI change to happend.
But most of the times could be because your are trying to update a view element within another view, say UICollectionView inside a UIViewController. In order to solve this you should call async method inside the method that makes this UI update
I am having the following situation.
I am using a WebkitView to display some session information. In most places it's generated when the ViewController comes to life, but I have one particular view in which I have to reload it on user interactions with buttons that change to next or previous month.
I have the following code:
// This is my connection to the storyboard element
#IBOutlet weak var areaNotasMes: WKWebView!
After that I have a function that does the URL handling:
func actualizarUrlNotasMes(fechaNueva: Date) {
let formateadorAdicional = DateFormatter()
formateadorAdicional.dateFormat = "yyyyMM"
let url = URL(string: "https://myurl/\(formateadorAdicional.string(from: fechaNueva))")
areaNotasMes.load(URLRequest(url: url!))
}
And I have a button event that uses the function with the next YEAR_MONTH combination like this:
#IBAction func mesSigPressed(_ sender: UIButton) {
// Some more code to get the fechaActual variable
actualizarUrlNotasMes(fechaNueva: fechaActual)
// Some more code
}
So, basically what's happening is that it loads the first time I open the ViewController, but when I click on the button to change to the next month, the date gets changed, correctly generated and passed to the function. It generates the correct URL, but when the areaNotasMes.load(...) function runs, nothing refreshes on the WebKitView. I tried adding areaNotasMes.reload(), but it also did nothing. Do I have to like destroy and recreate the WebKitView each time I change the URL? Or am I not handling the URL change correctly?
Also, the console pops up some of these messages from time to time, not always:
[BoringSSL] nw_protocol_boringssl_get_output_frames(1301) [C5.1:2][0x7fea2d201de0] get output frames failed, state 8196
TIC Read Status [5:0x0]: 1:57
No you don't need to re-initialize the webview when changing the URL. I can't tell the issue with the information you provided. I would advise that you set the ViewController as navigationDelegate of the webview and implement these method to try to diagnose the issue :
func webView(WKWebView, didStartProvisionalNavigation: WKNavigation!)
func webView(WKWebView, didFail: WKNavigation!, withError: Error)
//Called when an error occurs during navigation.
func webView(WKWebView, didFailProvisionalNavigation: WKNavigation!, withError: Error)
Documentation here
I think I actually managed to fix this in the most random way. I thought maybe there's some reload function (except for .reload()) so using the auto completion of syntax, I came up with the following command:
areaNotasMes.reloadInputViews()
Apparently .reloadInputViews() is a void function inherited from UIView which updates the custom input and accessory views when the object is the first responder. You can check it here: reloadInputViews()
It does send some Error Domain=NSURLErrorDomain Code=-999 "(null)" although it actually works as supposed and refreshes the WebKitView information.
I hope this helps someone else.
So I tried learning Swift well enough to recreate my programs in it, didn't work so well and I didn't get very far. Tried running my C++ functions from Obj-C++ source by calling the functions, didn't work and the project refused to open again after the first time I closed it. I don't find object oriented programming very intuitive in the first place so I'd like to avoid Obj-C.
I already have both an Automator standalone workflow and a Service (that do the same thing) which is get the programs I need, display confirmation, run the program in a terminal window with stdout, and display a notification before exiting. This is everything I need it to do when a specific button is pressed.
So how would I go about linking this button to an Automator func run() block in Swift? I know the command that needs to be used but like I said I don't find object oriented programming very intuitive so I need to know the context in which that function is used. Would following block be enough in practice or would it need more specification?
#IBOutlet weak var testButton(NSButton!)
#IBAction testButton(_ sender: AnyObject)
{
let guard Bundle.main.path(forName: "test",forType:"workflow")
else
{
print("Could not find 'test.workflow'")
return
}
let URL="//location of file"
class func run(at: URL, withInput: nil)
}
Am I missing something about how to do this or is the above enough? Secondarily can someone please give an example as to the format of a file URL where the file is located in the bundles "Resources" folder?
Also would the class remain the word class or should I be specifying a custom class? Can someone please give me a realworld example of this block/concept in practice?
Here's a testButton function that should work:
#IBAction func testButton(_ sender: AnyObject) {
guard let workflowPath = Bundle.main.path(forResource: "test", ofType: "workflow") else {
print("Workflow resource not found")
return
}
let workflowURL = URL(fileURLWithPath: workflowPath)
do {
try AMWorkflow.run(at:workflowURL, withInput: nil)
} catch {
print("Error running workflow: \(error)")
}
}
Notes:
You need to import Automator at the top of your source file in order for the Swift compiler to recognize the AMWorkflow class
You need to add test.workflow to your project
I've already searched a lot but any answer fixed the problem.
I've created an app group, selected it on both app and today extension, they're linked to the same group now. I'm trying to load data from the app and display it on a table view on the today extension, the thing is that I'm getting a crash saying that my array is nil, and it cannot be nil. I don't know why tho, cause I'm putting the data into the array. Here is my code:
func handleData() {
let defaults = NSUserDefaults(suiteName: "MY APP GROUP HERE")
if let descriptionsArr = defaults?.valueForKey("descriptions") as? [String] {
descriptions = descriptionsArr
}
defaults?.synchronize()
}
So, I'm pretty sure the app group is spelled right, and the value key. What could it be that is making my array nil? Really need help!
Thanks.
I have a Swift application that has data I want to save using the methods described in this question. Now, I need to know what is the proper way to link these actions to the File -> Save/Save As menu item and the File -> Open menu item. This isn't a document-based application.
I'm running Xcode 6.4 on OS X 10.10.4.
Create an IBAction function and link it to the XIB via Interface Builder.
Create an open/save panel in that function and let the user select the file name and location, use the returned NSURL array for saving/loading path. (after converted to required object type, of course.)
There are lots of example codes almost everywhere, either Objective-C or Swift.
In Swift 3, it may seem odd because it's using 'First Responder' but all you have to do is add the following code to your NSViewController class that is set as the Custom Class on a storyboard. It does not have to be connected like other #IBAction functions.
class Test: NSViewController {
#IBAction func saveDocument(_ sender: Any?) {
// code to execute for save functionality
// following line prints in debug to show function is executing.
// delete print line below when testing is completed.
Print("save")
}
#IBAction func openDocument(_ sender: Any?) {
// code to execute for open functionality here
// following line prints in debug to show function is executing.
// delete print line below when testing is completed.
print("open")
}
}