After updating Xcode to 6.3 today I finally was able to totally remove sqlite.swift and reinstall it. And after having fixed about 50 errors caused by something changing I am down to about 15 errors remaining and all of them have something to do with the new sqlite.swift.
I have searched for new docs to cover the syntax changes to no avail. Some errors I have found other posts about and was able to fix.
So this function that used to work now complains about the ? after the delete()?... The error message is "Optional chain has no effect, expression already produces Int?'. The recommendation is to remove the ?
func delete(id: Int) {
let rows = db[schema.tableName]
rows.filter(schema.id == id).delete()?
}
If I remove the ? after delete() then it tells me "cannot invoke 'delete' with no argument". I searched the source code and the code completion, all of which does not show any arguments.
Also on update statements I now get this error:
Example code:
rows.filter(schema.id == id)
.update(schema.acctID <- acctID, schema.accessCode <- accessCode, schema.status <- 0)
Error: cannot invoke 'update' with an argument list of type '(Setter, Setter, Setter)'
Swift 1.2 removed the ability to coerce using a trailing ?. You can use ! if the statement shouldn't fail:
func delete(id: Int) {
let rows = db[schema.tableName]
rows.filter(schema.id == id).delete()!
}
Or you can chain the delete() call to a tuple member, instead:
rows.filter(schema.id == id).delete().changes
This has been a continual support issue, so the interface may change in the near future.
The update() call needs to be fixed the same way:
rows.filter(schema.id == id)
.update(
schema.acctID <- acctID,
schema.accessCode <- accessCode,
schema.status <- 0)! // or .changes
Related
I am using err113 as part of golangci-lint.
It is complaining about ...
foo_test.go:55:61: err113: do not define dynamic errors, use wrapped static errors instead: "errors.New(\"repo gave err\")" (goerr113)
repoMock.EXPECT().Save(gomock.Eq(&foooBarBar)).Return(nil, errors.New("repo gave err")),
^
foo_test.go:22:42: err113: do not define dynamic errors, use wrapped static errors instead: "errors.New(\"oops\")" (goerr113)
repoMock.EXPECT().FindAll().Return(nil, errors.New("oops"))
^
What is best way to fix this ?
Quoting https://github.com/Djarvur/go-err113
Also, any call of errors.New() and fmt.Errorf() methods are reported
except the calls used to initialise package-level variables and the
fmt.Errorf() calls wrapping the other errors.
I am trying to get a idiomatic example for this.
Declare a package-level variables as suggested:
var repoGaveErr = errors.New("repo gave err")
func someFunc() {
repoMock.EXPECT().Save(gomock.Eq(&foooBarBar)).Return(nil, repoGaveErr)
}
Every call to errors.New allocates a new unique error value. The application creates a single value representing the error by declaring the package-level variable.
There are two motivations for the single value:
The application can compare values for equality to check for a specific error condition.
Reduce memory allocations (although probably not a big deal in practice)
The value io.EOF is a canonical example.
Since GO 1.13 you can define a new error type, wrap it and use it.
for example, if you want to return an "operation not permitted" + the operation.
you need to implement something like
var OperationNotPermit = errors.New("operation not permitted")
func OperationNotFoundError(op string) error {
return fmt.Errorf("OperationNotPermit %w : %s", OperationNotPermit, op)
}
then in your code, when you want to return the error,
return nil, OperationNotFoundError(Op)
Let's back to question case:
first, define the custom error and the wapper
var repoError = errors.New("repositoryError")
func RepositoryError(msg string) error {
return fmt.Errorf("%w: %s", repoError,msg)
}
then in your code,
repoMock.EXPECT().Save(gomock.Eq(&foooBarBar)).Return(nil, RepositoryError("YOUR CUSTOM ERROR MESSAGE"))
Since it hasn't been said before, you probably don't need to define package level errors for tests. Given the idea is to wrap errors so they can be compared and unwrapped in the caller, returning a dynamic error in a test is fine as long as the purposes of your test are served.
I'm having trouble converting optional input String to Int in order to do calculations on it.
let odoField = UITextField() // allows entry of text to iOS field
odoField.text = "12500" // simulated input
let odoString = odoField.text
// now here is where I get trouble...
if let odoInt = odoString.toInt() {
distance = Double(odoInt)
}
Apparently the toInt suffix is no longer part of Swift. I have tried the following:
if let odoInt = Int(odoString)() {
But then I get the error "Optional type String? is not unwrapped" and a suggestion to put a ! or ?, as in:
if let odoInt = Int(odoString!)() {
But then I STILL get the euro about unwrapping, with the suggestion that I add yet another !, then when I do that, another error that I get rid of the parens, like this:
if let odoInt = Int(odoString!)! {
And then I get ANOTHER error that "Initializer for conditional binding must have Optional type, not 'Int'."
I'm trying to create conditional unwrapping, here.
Help!
First thing to understand is that UITextField.text returns an optional string, so in your code, odoString is of type String?. Also, keep in mind that the Int constructor takes a String, not a String? so you have to unwrap the String? before you can use it. Just putting a ! after the variable (as in Int(odoString!)) will crash your app if the odoString is nil. Better would be something like this:
if let s = odoString, odoInt = Int(s) {
// odoInt is of type Int. It is guaranteed to have a value in this block
}
I've tested Daniel T's answer and it worked.
I have a situation where I want to get the result of a text field back as an optional Int. You can extend this to cover your case using the following code:
let odoInt = odoField.text != nil ? Int(odoField.text!) : nil
if let odoInt = odoInt {
// Use unwrapped odoInt here
}
Another option - for a more compact solution - is to use a flatMap:
let number = odoString.flatMap { Double($0) } ?? 0.0
In fact, it appears that the answer in Swift 2 (Xcode 7 beta 6) is simpler than anything above. The code does not choke on a nil value for odoString when I do e.g. the following:
if let odoInt = Int(odoString!) {
distance = Double(odoInt)
}
I therefore surmise, barring deeper knowledge to the contrary, that the compiler does treat this as "if the statement is True (the right side is valid), then define and initialize the variable, and continue with execution." I welcome further feedback. This does render unnecessary a lot of the extra code that is suggested above.
I recently updated to Xcode 6.3 with Swift 1.2, and received over 300 errors, most of which involved adding an exclamation point. One type of issue that will not go away, however, is the error that "'_' is not convertible to 'StringLiteralConvertable'". This appears multiple times, in these situations:
PFCloud.callFunctionInBackground("modifyUser", withParameters: ["objectId":user.objectId, "key":"won", "value":won as AnyObject],block:nil)
PFCloud.callFunctionInBackground("modifyUser", withParameters: ["objectId":friend.objectId, "key":"parties", "value":played], block:nil)
PFCloud.callFunctionInBackground("modifyUser", withParameters: ["objectId":creator.objectId, "key":"left", "value" :left], block: {
(error) in
self.remainingPotatos = PFUser.currentUser()["left"] as! Int
})
The error appears to be on the strings that are the keys of the dictionary, however, they are by definition StringLiteralConvertable. What gives?
UPDATE
This appears to be another case of Xcode detecting an error but not telling which one. After adding '!' after 'objectId', the error switched to being about the data type of the arguments. The error message is:
Cannot invoke 'callFunctionInBackground' with an argument list of type '(String, withParameters:NSDictionary, block(_)->(_)'
Which part is the problem? (Also, changing error to 'error:NSError?' gives a similar result.
UPDATE
Looking at the Parse documentation, the block signature should be
^(id result, NSError *error)
I tried changing the block to
{
(result, error) in
//code
}
But still receive the same error
Possibly not the only problem, but you appear to have a key in one of your dictionaries of "value"! which isn’t valid in 1.2 (and would have compiled, but not made much sense, in 1.1)
import Foundation
let left = "blah" as NSString
let dict = ["value"!:left]
results in error: '_' is not convertible to StringLiteralConvertible
This was a problem with Xcode detecting the wrong error at the wrong place. Adding an '!' after "currentUser()" fixed the problem, and the lines with nil blocks lost their errors with a clean.
I am currently learning Swift and I am experimenting with Core Data where I would like to save a linked list. To add an element at the end of the list I have a while-loop like this:
var curr = start
while (curr.nextElem != nil) {
curr = curr.nextElem
}
The problem is though that curr.next != nil seems to be invalid, following error is shown: 'ListElem' is not convertible to UInt8
I noticed this error a few times before but always found a way around comparing but how can this be done in this case?
Your ListElem.nextElem property seems to be returning an actual ListElem, so it can never be nil. For it to be able to be nil, it has to be of optional type (ListElem?).
Also, try the Xcode 6.3 beta — most of the error messages where Swift 1.1 said "I dunno what you're doing, so I'll just say you can't convert it to UInt8" have been replaced with better diagnostics in Swift 1.2.
I'm trying to intercept events using Gdk.Window.AddFilter(Gdk.FilterFunc) in Mono. So far, I have been able to hook up the filter function, but now I am trying to use the events in the filter function.
This is what I have in the filter function so far:
private Gdk.FilterReturn FilterFunction(IntPtr xEvent, Gdk.Event evnt)
{
if (evnt.Type == Gdk.EventType.KeyPress)
{
Gdk.EventKey eventKey = (Gdk.EventKey)evnt; // fails here
if (eventKey.Key == this.key && eventKey.State == this.modifiers)
{
this.OnPressed(EventArgs.Empty);
}
}
return Gdk.FilterReturn.Continue;
}
How can I convert the Gdk.Event to Gdk.EventKey? I have tried casting it, but that doesn't seem to work.
Edit: Oops! The problem was that I had accidentally added a semicolon to the if statement, making it an empty statement. For some reason, the Gdk.Event does not correspond to the XEvent, so I am now pursuing a solution that uses the XEvent instead.
Why don't you try printing out the type so you can see what it really is? (it may not be EventKey)
Like:
Console.WriteLine (evnt.GetType ());
(or pause it in a debugger and examine it to see the type)