DynamoDB query returning nil every time even when the object exists - swift

I have a query that returns nil each time I run it despite there being items with the key I pass.
I set my expression to the following:
queryExpression.keyConditionExpression = "#uID = :uidValue"
// in my model class
var uID: String?
uidValue is the value I'm comparing "uID" to.
I've read through AWS's documentation on this and haven't found anything that's helped.
//implementation of query
let dynamoDbObjectMapper = AWSDynamoDBObjectMapper.default()
dynamoDbObjectMapper.query(GameTracker.self, expression: queryExpression) { (output: AWSDynamoDBPaginatedOutput?, error: Error?) in
if(output == nil){
//create new user here, this keeps getting run each time
}else{
//user found, run other logic
}
}
I'm running uID's that I know exist in my table, but it keeps returning nil each time and throwing an error. Unfortunately, AWS docs on this don't offer many new insights into what might be going wrong from what I've found.

I resolved this by assigning uID as my partition key and just searching by hashkey instead.

Related

Getting nil values when `map`-ing over array of entities

I'm using Core Data in an iOS app and executing the following Swift code which results in an error at the second line:
let movies = (try? container.newBackgroundContext().fetch(request)) ?? []
return movies.map { $0.name! } // error: unexpectedly found nil while unwrapping...
Note that in the example above it's 100% certain that there is no entity in movies with nil in name. The corresponding attribute in the Core Data model is set to not optional.
When I change the code as shown below (i.e. not inlining newBackgroundContext()) there is no error:
let context = container.newBackgroundContext()
let movies = (try? context.fetch(request)) ?? []
return movies.map { $0.name! } // no error this time
I'm quite new to Swift and assume it has something to do with memory management (e.g. context is deinited prematurely) but I would appreciate an actual explanation of why the error occurs in the first code listing.
Whenever you run map function on your array it returns an optional value. seems like there is no value in name and you are doing force unwrapping. try to use compactMap.
movies.compactMap { $0.name }

.prepare vs. .select

I have a working connection to a database in an iOS10 app, using SQLite.swift.
I want to select details for a specific university where I have an IHE_ID passed in from another view controller.
I would like to just select the row for that specific university, but I can't get a query to work. I can however loop through all the data with a prepare and then choose the one I need from that, which of course is more resource intensive than I need since I already have the specific IHE_ID passed in as anIHE Int from the sending view controller.
connection is working so omitting that code...
do {
let db = try Connection(destinationDBPath, readonly: true)
let IHEs = Table("IHE")
let IHE_ID = Expression<Int>("IHE_ID")
let IHE_Name = Expression<String>("IHE_Name")
let IHE_COE_Url = Expression<String>("IHE_COE_URL")
let IHE_Sector = Expression<Int>("IHE_Sector")
let IHE_COE_Name = Expression<String>("IHE_COE_Name")
for ihe in try db.prepare(IHEs){
if (ihe[IHE_ID] == anIHE){
// build this string, otherwise ignore rest of dataset (doing this because query isn't working)
buildIHE = "Name: \(ihe[IHE_Name])\n"
buildIHE.append("URL: \(ihe[IHE_COE_Url])\n")
// buildIHE.append("Sector: \(ihe[IHE_Sector])\n")
if (ihe[IHE_Sector] == 0) {
buildIHE.append("Sector: Public\n")
} else {
buildIHE.append("Sector: Private\n")
}
buildIHE.append("College of Education Name: \(ihe[IHE_COE_Name])\n")
}
}
print ("Got through building IHE portion of view")
What I'd like to do is use this instead of the for loop.
if let query = IHEs.select(IHE_ID,IHE_Name,IHE_COE_Url,IHE_Sector,IHE_COE_Name).filter(IHE_ID == anIHE){
print("Query successful for \(anIHE) with name \(query[IHE_Name])")
// more actions to build the string I need would then occur
} else {
print("Query has failed or returned nil")
}
Finally, I'll use the selected elements if I can get the query to work.
I think I probably just have something wrong with my syntax on the query, but any help is appreciated.
The line with the "if let query" has this error in Xcode:
Initializer for conditional binding must have Optional type, not 'Table'.
This leads me to think it's something with my use of the .select statement and just new to using SQLite.swift and swift in general.
Last thing is that anIHE comes into this function as an Int, and IHE_ID is Expression as shown in this code. I'm thinking this may be part of the problem.
The Initializer for conditional binding must have Optional type error means that the expression on the right of the if let v = expr statement is not an Optional: there is no point using if let, and the Swift compiler says that you should just write let v = expr.
And indeed, IHEs.select(...).filter(...) returns a non-optional value of type Table.
It is not the database row you expect, because the query has been defined, but not executed yet. After all, you weren't using db: where would the rows be loaded from?
The solution is to bring back the database connection, and load a single row. This is done with the pluck method.
if let ihe = try db.pluck(IHEs.select(...).filter(...)) {
print("Name \(ihe[IHE_Name])")
}

Deleting object from parse-server code causing error?

I am developing an app in Xcode using swift and am using a heroku-hosted parse-server as my database. I want to be able to delete an object from the database, but I keep getting an error when trying to type out the code. Here is what I have:
{
let removingObjectQuery = PFQuery(className: "GoingTo")
removingObjectQuery.whereKey("objectId", equalTo: goingToSelectionID)
removingObjectQuery.findObjectsInBackground(block: { (object, error) in
if let objects = object{
print("Object found")
for object in objects{
object.deleteInBackground()
}
}
})
}
But the delete .deleteInBackground keeps sending an error to in the code line saying that ".deleteInBackground is not a member of [PFObject]"... except that I thought it is a member of that value type?
Edit: Syntax fixed to allow calling of .deleteInBackground but now am receiving error in logs (which does not crash the app) that "[Error]: Object not found". The object is for sure in the DB and whereKey equalTo: is adequately described... (goingToSelectionID is indeed the objectId in the DB... checked this by printing to logs). Not sure what is wrong?
The findObjectsInBackground method doesn't return results of type PFObject, but [PFObject], which is an array of PFObjects... If you want to delete the whole array, you can use the class method deleteAllInBackground like so:
PFObject.deleteAllInBackground(objectt, block: nil)
Or you can iterate through the array:
for objectt in object! {
objectt.deleteInBackground()
}

How to address key of retrieved object, in Realm, Swift?

I have created DB for my iOS mobile app using Realm, writing with Swift.
I am trying to find way to look up for matching username and password in DB
This is what I have currently, Attempting filtering and get an object with matching username
I am trying to address attribute/key called password from retrieved object
#IBAction func SignInCheck(sender: AnyObject) {
let realm = try! Realm()
var currentlogin = realm.objects(UserRecords).filter("name = LogUsernameTextField.text")
//this line causes SIGABRT to be thrown
if currentlogin.password == LogPasswordTextField.text { //This is the incorrectly addressed line
....
}
}
The issue maybe that I am not understanding how objects work in the right way, nor knowing the right syntax to address what I want.
I suspect it is in form of Result but I am still unable to find way to address desired information.
Here is the table structure for your information
class UserRecords: Object {
dynamic var username: String = ""
dynamic var password: String = ""
dynamic var latitude: Float = 0
dynamic var longtitude: Float = 0
}
I am open for suggestions better solution and ways of looking up/matching passwords in the table too, if any.
Thanks in advance
You are using a property called name in your filter string but in your UserRecords class the property is called username. Also you have to create the filter string differently:
var currentlogin = realm.objects(UserRecords).filter("username = '\(LogUsernameTextField.text!)'")
Also be aware that the filter method returns a list of UserRecord objects that match the filter and not a single object. So calling if currentlogin.password == ... will cause an error.
The list only has 1 item (because the username is unique) but it is still a list. So to access the UserRecord object you can call first:
var currentlogin = realm.objects(UserRecords).filter("name = LogUsernameTextField.text!").first
Also the text property of UITextField returns an Optional, so you have to unwrap it.

Parse.com Access objects with 'includeKey'

Good Day,
I use includeKey to fetch pointer objects, but I can use them... Here is my code:
var diagQuery = PFQuery(className: "CaseDiagnosis")
diagQuery.whereKey("patientcase",matchesQuery: caseQuery)
diagQuery.includeKey("patientcase")
var remoteDiags = diagQuery.findObjects()
println(remoteDiags)
console output:
[<CaseDiagnosis:IvQyy1i1ic:(null)> {
diagcode = "Z01.1";
firstcontact = "<FirstContact:7L3HB9Vnp2>";
patientcase = "<PatientCase:T2A4t37Iaw>";
}]
How do I access 'patientcase'?
My code so far:
for diag : PFObject! in remoteCases as [PFObject]{
// This does not require a network access.
var p = diag["patientcase"] as PFObject <----------Error
println("retrieved related post: \(p)")
}
I get an error:
fatal error: unexpectedly found nil while unwrapping an Optional value
What am I doing wrong?
From the sounds of the error, it might be complaining that one of the values in the remoteCases array is nil, try logging diag inside the loop.
Also be aware that if the PatientCase the pointer is pointing to has been deleted, you'll have issues also. The pointer will have the ID but the full object will be nil.