Reputation: 95
The main question is in func all
. I want to get the Pers
model when my distance is less than 100 meters(not include myself). I know that my return statement can't write in a for loop. But I don't actually know how to assign my filter.
controller:
import Foundation
import Vapor
import Fluent
import CoreLocation
final class UserLocationController{
func take (_ req: Request) throws -> HTTPStatus{
let userlocation = try req.content.decode(UserLocation.self);
let defalts = UserDefaults.standard
defalts.setValue(userlocation.latitude, forKey: "latitude")
defalts.setValue(userlocation.longitude, forKey: "longitude")
return HTTPStatus.ok
}
func all (_ req: Request) throws ->EventLoopFuture<[Pers]>{
let users = try req.content.decode([UserLocation].self)
let latitude = UserDefaults.standard.double(forKey: "latitude")
let longitude = UserDefaults.standard.double(forKey: "longitude")
let userlocation = CLLocation(latitude: latitude, longitude: longitude)
let newUsers = users.filter{ user in
let location = CLLocation(latitude: user.latitude, longitude: user.longitude)
return location.distance(from: userlocation) < 100
}
for value in newUsers{
let user = value.user
return Pers.query(on: req.db).filter(\.$user.$id == user).all()
}
}
}
UserLocation
model:
import Foundation
import Vapor
import FluentPostgresDriver
struct UserLocation: Content{
var id:UUID?
var latitude: Double
var longitude: Double
var user: User.IDValue
}
Pers
model:
import Foundation
import Fluent
import Vapor
import FluentPostgresDriver
final class Pers:Model,Content{
static let schema = "pers"
@ID(key: .id)
var id:UUID?
@Field(key: "姓名")
var name: String
@Field(key: "IG帳號")
var account: String
@Field(key: "頭像")
var picture: String
@Field(key: "年紀")
var age: String
@Field(key: "生日")
var birth: String
@Field(key: "居住城市")
var city: String
@Field(key: "興趣")
var hobby : String
@Parent(key: "user_id")
var user: User
init(){}
init(id:UUID?=nil, name:String, account:String, picture:String ,age:String, birth:String, city:String, hobby:String, userId:UUID){
self.id=id
self.name=name
self.account=account
self.picture=picture
self.age=age
self.birth=birth
self.city=city
self.hobby=hobby
self.$user.id=userId
}
}
Upvotes: 1
Views: 70
Reputation: 5565
The short answer is that you can use the subset query to get all the users from a subset, e.g.
return Pers.query(on: req.db).filter(\.$user.$id ~~ newUsers.compactMap { $0.id }).all()
However there are a number of serious issues with your code. For starters if you're planning on deploying to Linux you cannot use CoreLocation. Second you're doing the location filter on the server instead of the database, so if you have a lot of users that query is going to be slow as you need to get every user from the database. A PostGIS query would be much more efficient.
Finally what are you trying to achieve with user defaults? They should not be used in server-side Swift. The way you have it is that the coordinates will be taken from whoever accessed the take
endpoint last, even if it's not the same person accessing the all
endpoint.
Upvotes: 2