How to access query parameters in vapor 3 - swift

Basically the title. I want to know how to use url query parameters in Vapor 3. I can't seem to find anything in the docs on it.
e.g. /objects?fancy=true, how do I access the fancy parameter.

You can do something like e.g.:
guard let fancy = req.query[Bool.self, at: "fancy"] else {
throw Abort(.badRequest)
}
Or if it's optional you could do
if let qFancy = try? req.query.get(Bool.self, at: "fancy") {
fancy = qFancy
} else {
fancy = false
}

Related

How to check if json has a key without SwiftyJSON in swiftUI?

I need to check a json response and find out if the response has a key.
I found other similar questions but they are working with libraries like SwiftyJSON.
I don't want to use that.
I need to know if its possible to do this without using any third party libs?
My current code is this:
let data = str.data(using: .utf8)!
do {
if let jsonArray = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary
{
print(jsonArray)
// I NEED TO DO CHECKS HERE...
// something like this:
if (jsonArray['someKey'] = exist){
do something here
}else{
do something else
}
}
}
Is this possible at all?
Try using:
if let value = jsonArray["someKey"] {
// If key exist, this code will be executed
} else {
// If key does not exist, this code will be executed
}

Extract PDF Highlights with PDFKit

I'm trying to extract all Highlights using PDFkit in a macOS app. Here's the code I'm using:
guard let path = item.filePath else { return }
let document = PDFDocument(url: URL(fileURLWithPath: path))
guard let numberOfPage = document?.pageCount else { return }
for i in 0...numberOfPage - 1 {
let pages = document?.page(at: i)
guard let annotations = pages?.annotations else { continue }
for annotation in annotations {
if annotation.type == "Highlight" {
print(annotation.contents)
self.annotations.append(annotation)
}
}
}
The problem is that print(annotation.contents) always return "Optional("")". I tried several pdf, and the result is always the same. The thing is that if I do print(annotation.color), it return the correct color of the given highlights.
Is there something wrong with my code that I didn't figure out? Or is this a normal behavior of PDFKit?
Use PDFAnnotationSubtype.highlight.rawValue to get the key for the highlights. If you print that value, you will see that it's /Highlight. Even though we know the key now, you should still use the enum value, in case anything ever changes in PDFKit.
So in your case...
if annotation.type == PDFAnnotationSubtype.highlight.rawValue {
If that confuses you, familiarize yourself with Enums and Raw Values.

Swift access closure members programmatically

I am building a Swift app and using PromiseKit to make the async features more readable.
From the PromiseKit docs, I can see that it supports multiple concurrent promises. I wrote some code as follows to generate promises in a for loop then wait for them all to get fulfilled.
for index in 0...100 {
let urlString = "https://someurl.com/item/\(index)"
guard let url = URL(string: urlString) else { return }
requestPromises += [URLSession.shared.dataTask(.promise, with: url).validate()]
}
firstly {
when(fulfilled: requestPromises)
}.done {
// process results
}
The example in the docs shows to write the promise as:
firstly {
when(fulfilled: operation1(), operation2())
}.done { result1, result2 in
//…
}
My problem is I don't want to write out result1, result2, ... result100. Is there a way to programmatically access the results?
I was able to solve this the following way (thanks #MadProgrammer):
for index in 0...100 {
let urlString = "https://someurl.com/item/\(index)"
guard let url = URL(string: urlString) else { return }
requestPromises += [URLSession.shared.dataTask(.promise, with: url).validate()]
}
firstly {
when(fulfilled: requestPromises)
}.done { results in
// process results
}

Swift: guard let and where - the priority

Sometimes, I want to use guard combined with let & where to simplify my code. But I wonder what's the priority of let and where. For example:
class Person {
func check() -> Bool? {
print("checking")
return nil
}
}
func test(dont: Bool) {
let person = Person()
guard let check = person.check() where dont else {
print("should not check")
return
}
print("result: \(check)")
}
test(false)
As you can see the console result, printed output are:
checking
should not check
For the condition of let check = person.check() where dont in guard <condition> else { } syntax, even the expression in where doesn't relate to the results of expression in let, Swift seems to execute let first then check where later. Sometimes in my code, let optional binding takes lots of calculation and where is only a simple condition without relying on let results, should I move the where out of guard? Or I'm wrong about the priority or let & where?
You are right, in your Swift 2 code
guard let check = person.check() where dont else { }
the conditional binding let check = ... is checked first, and only if that succeeds, the boolean condition dont is checked. You can use
guard dont, let check = person.check() else { }
to check the boolean condition first.
This "asymmetry" in the syntax has been removed in Swift 3:
All guard clauses are separated by commas and the
where keyword is not used anymore. So you have
guard let check = person.check(), dont else { }
// or
guard dont, let check = person.check() else { }
The conditions are checked from left to right with short-circuiting,
i.e. if one condition fails then the else-block is executed without
checking the remaining conditions.

Making a variable from if statement global

While encoding JSON, I´m unwrapping stuff with an if let statement, but I'd like to make a variable globally available
do {
if
let json = try JSONSerialization.jsonObject(with: data) as? [String: String],
let jsonIsExistant = json["isExistant"]
{
// Here I would like to make jsonIsExistant globally available
}
Is this even possible? If it isn't, I could make an if statement inside of this one, but I don't think that would be clever or even possible.
delclare jsonIsExistant at the place you want it. If you are making an iOS App, than above viewDidLoad() create the variable
var jsonIsExistant: String?
then at this point use it
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: String],
let tempJsonIsExistant = json["isExistant"] {
jsonIsExistant = tempJsonIsExistant
}
}
This could be rewritten like so though
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: String] {
jsonIsExistant = json["isExistant"]
}
} catch {
//handle error
}
If handled the second way, then you have to check if jsonIsExistant is nil before use, or you could unwrap it immediately with a ! if you are sure it will always have a field "isExistant" every time that it succeeds at becoming json.
It doesn't make sense to expose a variable to the outside of an if let statement:
if let json = ... {
//This code will only run if json is non-nil.
//That means json is guaranteed to be non-nil here.
}
//This code will run whether or not json is nil.
//There is not a guarantee json is non-nil.
You have a few other options, depending on what you want to do:
You can put the rest of the code that needs json inside of the if. You said you didn't know if nested if statements are "clever or even possible." They're possible, and programmers use them quite often. You also could extract it into another function:
func doStuff(json: String) {
//do stuff with json
}
//...
if let json = ... {
doStuff(json: json)
}
If you know that JSON shouldn't ever be nil, you can force-unwrap it with !:
let json = ...!
You can make the variable global using a guard statement. The code inside of the guard will only run if json is nil. The body of a guard statement must exit the enclosing scope, for example by throwing an error, by returning from the function, or with a labeled break:
//throw an error
do {
guard let json = ... else {
throw SomeError
}
//do stuff with json -- it's guaranteed to be non-nil here.
}
//return from the function
guard let json = ... else {
return
}
//do stuff with json -- it's guaranteed to be non-nil here.
//labeled break
doStuff: do {
guard let json = ... else {
break doStuff
}
//do stuff with json -- it's guaranteed to be non-nil here.
}