CVaListPointer when using objectsWhere() querying Realm database - ios

I'm updating my code to swift 3.0. I use Realm for the database. I have the following line of code:
let thisJob = Jobs.objectsWhere("identifier == '\(identify)'")
The compiler throws an error because an extra argument is required. "Missing argument for parameter 'args' in call" The parameter is a CVaListPointer. I'm not sure how I'm supposed to use this argument. I tried:
let thisJob = Jobs.objectsWhere("identifier == '\(identify)'", args: CVaListPointer)
However, the compiler error with that line is "Cannot convert value of type CVaListPointer.Type to expected argument CVaListPointer."

Varargs in Objective-C interfaces aren't imported in Swift, which is why Realm has made a Swift wrapper for Realm Objective-C available: RLMSupport.swift. Add that to your project's source files as described in Realm's installation instructions and you'll be able to use Jobs.objectsWhere("identifier == '\(identify)'").
Though if identify can at all contain characters that should be escaped when doing string interpolation, you're better off passing it as a format argument:
Jobs.objectsWhere("identifier == %#", identify)

Related

Deedle, F# and read csv

I am facing an issue when I try to use the function Deedle.Frame.ReadCsv
I am trying to use the overload here: https://collective2.com/c2explorer_help/html/806c0295-1a9f-1bf4-50eb-a221419abe06.htm
let schemaSource = "dateRep (DateTime),,,,,,,,,"
let dataSource = Deedle.Frame.ReadCsv(path = "data.csv", schema = schemaSource)
When I do so, I get the following error:
error FS0503: A member or object constructor 'ReadCsv' taking 0 arguments is not accessible from this code location. All accessible versions of method 'ReadCsv' take 9 arguments.
What I do not get is that all but path are optional. If I use just:
Deedle.Frame.ReadCsv("data.csv")
It then works...
Any idea? I tried to find some resources on using overloaded functions from other .Net languages with optional parameters but I have not been successful.
I am not sure why the Intellisense/Signature shown in Visual Studio was wrong but using location = works...

outputting a value to a typedef pointer in swift

I'm almost certain the title of this isn't correct but here goes...
I'm bridging to an Objective-C class to set a typedef. The bridge is set up and I'm able to declare the typedef var correctly.
In Objective-C I also called a method from the same class that, when called, output a value to the variable TestHandle.
var TestHandle : TESTHANDLE
TestInit(&TestHandle)
When I try this using Swift 5 I get this error:
Cannot convert value of type 'inout TESTHANDLE' (aka 'inout UnsafeMutableRawPointer') to expected argument type 'UnsafeMutablePointer<TESTHANDLE?>?' (aka 'Optional<UnsafeMutablePointer<Optional<UnsafeMutableRawPointer>>>')
Any pointers?
Some observations:
TESTHANDLE appears to be an alias for UnsafeMutableRawPointer
&testHandle is taking a reference (a pointer to the location) of the testHandle, producing a value of type inout UnsafeMutableRawPointer
As the error says, your TestInit function takes a variable of type UnsafeMutablePointer<TESTHANDLE?>?, a.k.a. Optional<UnsafeMutablePointer<Optional<UnsafeMutableRawPointer>>>
Swift has some rules about how & automatically bridges to the various pointer types, but to be frank, I don't understand them very well.
As far as I know, the Swift pointer types cannot represent nil (0x000...000). To do that, they need to be wrapped within an optional. So when you see the type
Optional<UnsafeMutablePointer<Optional<UnsafeMutableRawPointer>>>
It's actually two "semantic" parts:
Optional<UnsafeMutablePointer< Optional<UnsafeMutableRawPointer> >>
↳ A nullable pointer to ... ↳ ... something that's a nullable pointer of unspecified (void) type
The reason you're getting your error is because &testHandle can only bridge your UnsafeMutableRawPointer to a Optional<UnsafeMutablePointer<UnsafeMutableRawPointer>>, but not the required Optional<UnsafeMutablePointer<Optional<UnsafeMutableRawPointer>>> (the difference is in that missing layer of "inner" nullability). To get around this, make your testHandle optional, yourself:
var testHandle: TESTHANDLE? // a.k.a. Optional<TESTHANDLE>, a.k.a. Optional< UnsafeMutableRawPointer>
Then, when you use the & operator, Swift will wrap your value in the required Optional<UnsafeMutablePointer< ... >> outter layer.
typealias TESTHANDLE = UnsafeMutableRawPointer
func testInit(_ p: UnsafeMutablePointer<TESTHANDLE?>?) {
print("Success!")
}
var testHandle: TESTHANDLE? = nil
testInit(&testHandle)

Using Xcode, Swift, and GRDB, why do I have to unwrap DatabaseQueue? before I can use its methods?

I'm using the GRDB library to integrate SQLite with my iOS application project. I declared a DatabaseQueue object in AppDelegate.swift like so:
var DB : DatabaseQueue!
In the same file, I had provided a function for connecting the above object to a SQLite database which is called when the app starts running. I had been able to use this in one of my controllers without problems (as in, the app doesn't have problems running using the database I connected to it), like so:
var building : Building?
do {
try DB.write { db in
let building = Building.fetchOne(db, "SELECT * FROM Building WHERE number = ?", arguments: [bldgNumber])
}
} catch {
print(error)
}
However, in another controller, the same construct is met with an error,
Value of optional type 'DatabaseQueue?' must be unwrapped to refer to member 'write' of wrapped base type 'DatabaseQueue'
with the only difference (aside from the code, of course) being that there are return statements inside the do-catch block, as the latter is inside a function (tableView for numberOfRowsInSection) that is supposed to return an integer. The erroneous section of code is shown below.
var locsCountInFloor : Int
do {
try DB.write { db in
if currentBuilding!.hasLGF == true {
locsCountInFloor = IndoorLocation.filter(bldg == currentBuilding! && level == floor).fetchCount(db)
} else {
locsCountInFloor = IndoorLocation.filter(bldg == currentBuilding! && level == floor + 1).fetchCount(db)
}
return locsCountInFloor
}
} catch {
return 0
}
Any help would be greatly appreciated!
As is often the case when you have a problem with a generic type in Swift, the error message is not helpful.
Here’s the real problem:
DB.write is generic in its argument and return type. It has a type parameter T. The closure argument’s return type is T, and the write method itself returns T.
The closure you’re passing is more than a single expression. It is a multi-statement closure. Swift does not deduce the type of a multi-statement closure from the statements in the closure. This is just a limitation of the compiler, for practical reasons.
Your program doesn’t specify the type T explicitly or otherwise provide constraints that would let Swift deduce the concrete type.
These characteristics of your program mean Swift doesn’t know concrete type to use for T. So the compiler’s type checker/deducer fails. You would expect to get an error message about this problem. (Possibly an inscrutable message, but presumably at least relevant).
But that’s not what you get, because you declared DB as DatabaseQueue!.
Since DB is an implicitly-unwrapped optional, the type checker handles it specially by (as you might guess) automatically unwrapping it if doing so makes the statement type-check when the statement would otherwise not type-check. In all other ways, the type of DB is just plain DatabaseQueue?, a regular Optional.
In this case, the statement won’t type-check even with automatic unwrapping, because of the error I described above: Swift can’t deduce the concrete type to substitute for T. Since the statement doesn’t type-check either way, Swift doesn’t insert the unwrapping for you. Then it carries on as if DB were declared DatabaseQueue?.
Since DatabaseQueue? doesn’t have a write method (because Optional doesn’t have a write method), the call DB.write is erroneous. So Swift wants to print an error message. But it “helpfully” sees that the wrapped type, DatabaseQueue, does have a write method. And by this point it has completely forgotten that DB was declared implicitly-unwrapped. So it tells you to unwrap DB to get to the write method, even though it would have done that automatically if it hadn’t encountered another error in this statement.
So anyway, you need to tell Swift what type to use for T. I suspect you meant to say this:
var locsCountInFloor: Int
do {
locsCountInFloor = try DB.write { db in
...
Assigning the result of the DB.write call to the outer locsCountInFloor is sufficient to fix the error, because you already explicitly defined the type of locsCountInFloor. From that, Swift can deduce the return type of this call to DB.write, and from that the type of the closure.

Cannot convert from `GLib.TypeClass' to `GLib.ObjectClass'

I was trying to compile libfriends (source) against valac (.28) and libgee (1.0). I specifically compiled these against Ubuntu-16.04 stack.
But I am getting following error
entry.vala:397.38-397.38: warning: if-statement without body
if (_selected != value);
^
entry.vala:172.52-172.86: error: Argument 1: Cannot convert from `GLib.TypeClass' to `GLib.ObjectClass'
binding_set = Gtk.BindingSet.by_class (typeof (InputTextView).class_ref ());
I don't really find anything wrong with code. Any Idea?
The entire buildlog is here: https://launchpadlibrarian.net/263631082/buildlog_ubuntu-xenial-i386.libfriends_0.1.2+14.10.20140709+201606051415~ubuntu16.04.1_BUILDING.txt.gz
I just checked and it compiles with valac-0.18, but doesn't compile with valac-0.28.
So there must have been a change between those valac versions that does more strict type checking in this case.
GLib.TypeClass (really GTypeClass in C) is the parent class of GLib.ObjectClass (really GObjectClass in C).
So the compiler is correct to not allow this without a cast. I don't know if the cast is correct in this situation, but it makes the code compile:
binding_set = Gtk.BindingSet.by_class ((ObjectClass) typeof (InputTextView).class_ref ())
See also valadoc for GObjectClass where a similar typecast is done in the example code:
http://valadoc.org/#!api=gobject-2.0/GLib.ObjectClass

getting error updating the sqlite

I am doing the project and I am structed in database path. I am using the sqlite database for storing. In this my problems is when I updating the table it showing the error. For database part I am using prewritten classes. I am calling that class method whenever I need. See below you can understand.
This below code is working fine
[DataCachingHelper updateTable:#"sendertable" data:dic3 where:#"MESSAGE_ID='1234'"];
but when I am sending the object to the "where", It showing some error.
[DataCachingHelper updateTable:#"sendertable" data:dic3 where:#"MESSAGE_ID=%#",#"hai"];
i am getting the error:
"too many arguments to methods call expected 3,have 4".
here MESSAGE_ID is VARCHAR TYPE
The issue is clear here. You can not pass string format because compiler compiles parameter before converting into string format. From your method declaration allowed parameters must be 3.
So compiler detect 4 parameter as you pass string with format.
Also in sqlite database for VARCHAR type field use double quotes for field values.
So your string should be like this:
NSString *whereClauseString = [NSString stringWithFormat:#"MESSAGE_ID = \"%#\"",#"hai"];
Or if value is pre known simply create string like this:
NSString *whereClauseString = #"MESSAGE_ID = \"hai\"";
And then use this string as third parameter for updateTable method:
[DataCachingHelper updateTable:#"sendertable" data:dic3 where:whereClauseString];
make this in two step.
NSString *strWhere=[NSString stringWithFormat:#"MESSAGE_ID='%#'",#"hai"];
[DataCachingHelper updateTable:#"sendertable" data:dic3 where:strWhere];

Resources