DynamoDB load nil Error - ios

I'm trying to load my data from dynamoBD and print them out with the labels.
Following the sample: https://github.com/awslabs/aws-sdk-ios-samples/tree/master/DynamoDBObjectMapper-Sample
I already created a table on the account and I can see their attributes using web browser.
Using this code to load data:
var tableRow: DDBTableRow?
func getTableRow() {
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
dynamoDBObjectMapper .load(DDBTableRow.self, hashKey: (tableRow?.PhotoId)!, rangeKey: tableRow?.UserId) .continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask!) -> AnyObject! in
if let error = task.error as? NSError {
print("Error: \(error)")
let alertController = UIAlertController(title: "Failed to get item from table.", message: error.description, preferredStyle: UIAlertControllerStyle.alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
alertController.addAction(okAction)
self.present(alertController, animated: true, completion: nil)
} else if let tableRow = task.result as? DDBTableRow {
self.photoIdLabel.text = tableRow.PhotoId
self.userIdLabel.text = tableRow.UserId
self.photoDateLabel.text = tableRow.PhotoDate
self.photoURLLabel.text = tableRow.PhotoURL
self.photoCategoryLabel.text = tableRow.PhotoCategory
}
return nil
})
}
In the log: tableRows [MyProject.DDBTableRow]? nil none.
The sample code is working fine, I don't know what wrong. Do I miss something before calling load? I feel very close to solve it. Please help!

Related

Checking if entity exist before saving it to core data swift4.

I'm trying to add data to Core Data in my application. When I save it without checking if it already exists it works fine. But I don't what duplicates in my core data so what I do I fetch all the entities with the name of entity im trying to add first and then check if it's 0 I add it else no. But I'm keep getting an error when trying to save. If anyone could help me with the problem.
This is my checking function:
func entityExists(name: String) -> Bool {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "name")
fetchRequest.includesSubentities = false
var entitiesCount = 0
do {
entitiesCount = try coreDataController.mainContext.count(for: fetchRequest)
}
catch {
print("error executing fetch request: \(error)")
}
if entitiesCount == 0{
return true
} else {
return false
}
}
This is my code when I save the data.
if entityExists(name: (scrimmagePassedOver?.name)!) == true{
coreDataController.saveContext()
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
let alert = UIAlertController(title: "Saved!", message: "You have saved your Scrimmage.", preferredStyle: UIAlertControllerStyle.alert)
// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
} else {
let alert = UIAlertController(title: "hey", message: "You have saved this Scrimmage before.", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
You can check the record from your core data like that:
func checkRecordExists(entity: String,uniqueIdentity: String,idAttributeName:String) -> Bool {
let context = getManagedObjectContext()
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: entity)
fetchRequest.predicate = NSPredicate(format: "\(idAttributeName) CONTAINS[cd] %#", createdDate)
var results: [NSManagedObject] = []
do {
results = try context.fetch(fetchRequest)
}
catch {
print("error executing fetch request: \(error)")
}
return results.count > 0
}
and managedObjectContext is:
func getManagedObjectContext() -> NSManagedObjectContext{
let delegate = UIApplication.shared.delegate as? AppDelegate
return delegate!.persistentContainer.viewContext
}
If you get false then save it.

Swift code to query AWS dynamoDB data base

I am building an app in Swift 2.3 and Xcode 8 and I need my app to query user information from a database (answers to questions they have answered earlier and saved in the database).
I have found some code (see it below) but I only get errors. I think that the problem is that code is looking for a specific item and I need to search the hash key for the unique id of the user so that every user who query's for their answers will get their specific information... any suggestions??
func updateAnswer() {
//first create expression
let queryExpression = AWSDynamoDBQueryExpression()
//second define the index name
queryExpression.indexName = "userID-index"
//3rd hashes
queryExpression.hashKeyAttribute = "userID"
queryExpression.hashKeyValues = ("us-east-1:97335bac-26d1-4b85-bc86-47091900df44")
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.defaultDynamoDBObjectMapper()
//tableRow?.UserId --> (tableRow?.UserId)!
dynamoDBObjectMapper .query(Notes.self, expression: queryExpression) .continueWithExecutor(AWSExecutor.mainThreadExecutor(), withBlock: { (task:AWSTask!) -> AnyObject! in
if (task.error == nil) {
if (task.result != nil) {
let note = task.result as! Notes
self.driverAccomplishment1.text = note._content
}
} else {
print("Error: \(task.error)")
let alertController = UIAlertController(title: "Failed to get item from table.", message: task.error!.description, preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: { (action:UIAlertAction) -> Void in
})
alertController.addAction(okAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
return nil
})
}

Optimizing a CloudKit sign-in on app launch with error handling. How can I better handle the optional chaining? Swift 3.0/Xcode 8.1

Is there a cleaner, swiftier solution to handle the optional chaining happening in my code below? I'm setting up the user for CloudKit access in my custom function runCKsetup():
func runCKsetup() {
container.requestApplicationPermission(.userDiscoverability) { (status, error) in
guard error == nil else {
if let error = error as? NSError {
if let errorDictionary: AnyObject = error.userInfo as? Dictionary<String, AnyObject> as AnyObject? {
let localizedDescription = errorDictionary["NSLocalizedDescription"]! as! String!
if localizedDescription! == "This operation has been rate limited" {
// Create an alert view
let alert = UIAlertController(title: "Network Error", message: localizedDescription!, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Test for Connection", style: UIAlertActionStyle.default) { (action) in
self.runCKsetup()
})
self.present(alert, animated: true, completion: nil)
} else {
// Create an alert view
let alert = UIAlertController(title: "Sign in to iCloud", message: localizedDescription!, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default) { (action) in
})
self.present(alert, animated: true, completion: nil)
}
}
}
return
}
if status == CKApplicationPermissionStatus.granted {
self.container.fetchUserRecordID { (recordID, error) in
guard error == nil else {
self.presentMessageAlert((error?.localizedDescription)!, title: "Error", buttonTitle: "Ok")
return }
guard let recordID = recordID else { return }
self.container.discoverUserIdentity(withUserRecordID: recordID, completionHandler: { (info, fetchError) in
//do something with the users names: e.g. print("\(info?.nameComponents?.givenName) \(info?.nameComponents?.familyName)")
})
}
}
}
}

Unexplained exception using the Google Places iOS SDK after upgrade to Xcode 8 and Swift 3.0

I cannot get even the demonstration code to work after converting it to swift 3.0. I have tried everything I can think of to no avail.
The exception is very unhelpful and the stack trace as well. (see the screenshot)
This is the swift 2.3 code, which works perfectly well:
#IBAction func getCurrentPlace(sender: UIButton) {
placesClient?.currentPlaceWithCallback({
(placeLikelihoodList: GMSPlaceLikelihoodList?, error: NSError?) -> Void in
if let error = error {
print("Pick Place error: \(error.localizedDescription)")
return
}
self.nameLabel.text = "No current place"
self.addressLabel.text = ""
if let placeLikelihoodList = placeLikelihoodList {
let place = placeLikelihoodList.likelihoods.first?.place
if let place = place {
self.nameLabel.text = place.name
self.addressLabel.text = place.formattedAddress!.componentsSeparatedByString(", ")
.joinWithSeparator("\n")
}
}
})
}
And this is the equivalent in swift 3.0:
#IBAction func go(_ sender: AnyObject) {
var placesClient: GMSPlacesClient?
placesClient = GMSPlacesClient.shared()
placesClient?.currentPlace(callback: {
(placeLikelihoodList: GMSPlaceLikelihoodList?, error: NSError?) in
if let error = error {
print("Pick Place error: \(error.localizedDescription)")
let alert = UIAlertController(title: "Error", message: "Couldn't find a location", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
return
}
if let placeLikelihoodList = placeLikelihoodList {
let place = placeLikelihoodList.likelihoods.first?.place
if let place = place {
self.testlabel.text = place.name
}
}
} as! GMSPlaceLikelihoodListCallback)
}
The exception stops me here: as! GMSPlaceLikelihoodListCallback
Anyone have a clue as to what's going on?
var placesClient: GMSPlacesClient?
placesClient = GMSPlacesClient.shared()
placesClient?.currentPlace(callback: { (place, error) in
if let error = error {
print("Pick Place error: \(error.localizedDescription)")
let alert = UIAlertController(title: "Error", message: "Couldn't find a location", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
return
}
if let placeLikelihoodList = place {
let place = placeLikelihoodList.likelihoods.first?.place
if let place = place {
self.lblOrigem.text = place.formattedAddress
}
}
})

stop animating ActivityViewIndicator after invalid login

I'm new to iOS programming and currently is playing around with some tutorial found online. I was trying to include an ActivityViewIndicator in the sign in view. When the "Sign In" button is tapped, an ActivityViewIndicator should show up and it show be hidden when sign in is invalid. My problem is where should i put the self.signInViewIndicator.stopAnimating(); when the sign in is invalid? I have enabled the Hides When Stopped option.
#IBAction func SignInButtonTapped(sender: AnyObject) {
let userUsername = userUsernameTextField.text
let userPassword = userPasswordTextField.text
if(userUsername.isEmpty || userPassword.isEmpty) { return}
signInViewIndicator.startAnimating()
// Send user data to server side
let myUrl = NSURL(string: "http://192.168.168.135:8080/userLogin.php")
let request = NSMutableURLRequest(URL:myUrl!)
request.HTTPMethod = "POST"
let postString = "username=\(userUsername)&password=\(userPassword)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
println("error=\(error)")
return
}
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary
if let parseJSON = json {
var resultValue = parseJSON["status"] as? String
println("result: \(resultValue)")
var isUserSignedIn:Bool = false
if(resultValue=="Success") {
isUserSignedIn = true
// Login is successful
NSUserDefaults.standardUserDefaults().setBool(isUserSignedIn, forKey: "isUserLoggedIn")
NSUserDefaults.standardUserDefaults().synchronize()
self.dismissViewControllerAnimated(true, completion: nil)
} else {
self.signInViewIndicator.stopAnimating()
var messageToDisplay:String = parseJSON["message"] as! String!
if(!isUserSignedIn)
{
messageToDisplay = parseJSON["message"] as! String!
}
dispatch_async(dispatch_get_main_queue(), {
// Display alert message with confirmation
var myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler:nil)
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil)
})
}
}
}
task.resume()
}
You almost got it rigth, you can never update the UI from a thread other than the main thread, as you was already displaying the alert in the main thread I just had to move your message "self.signInViewIndicator.stopAnimating()" to inside that dispatch block:
dispatch_async(dispatch_get_main_queue(), {
// Display alert message with confirmation
self.signInViewIndicator.stopAnimating()
var myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler:nil)
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil)
})

Resources