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
})
}
Related
I'm working on a banking app and I'd like to display alert message when a bank account is in collections (negative balance). I'd like to combine the success and failure case in one case and perhaps a way to refactor/clean the following code. The failure case (if the API Call fails) uses the Hardcoded strings for the Alert. The success case uses and retrieves strings from an API Call.
I'd like to know if I can combine the success and failure case in one case to keep it more clean, if possible. Thank you for your help.
private func checkBankAccountIsInCollections() -> Bool {
guard let accountModel = accountController.accountControllerViewModel?.accountModel else { return false }
let isAccountIsInCollections = accountModel.isAccountInCollections
if isAccountIsInCollections {
accountManager.getAPIContent { [weak self] result in
guard let self = self else { return }
switch result {
case .failure:
let alertWithNoAPIContentController = UIAlertController(
title: InternalStrings.collectionHeader,
message: InternalStrings.collectionMessage,
preferredStyle: .alert
)
let okAction = UIAlertAction(title: InternalStrings.collectionHeader.buttonTitle, style: .cancel) { _ in }
alertWithNoAPIContentController(okAction)
self.present(alertWithNoAPIContentController, animated: true, completion: nil)
case let .success(ContentModel):
let collectionsAPIContent = ContentModel.collectionsAccountElements
let alertWithAPIContentController = UIAlertController(
title: collectionsAPIContent?.header,
message: collectionsAPIContent?.description,
preferredStyle: .alert
)
let okAction = UIAlertAction(title: collectionsAPIContent.buttonTitle, style: .cancel) { _ in }
alertWithAPIContentController.addAction(okAction)
self.present(alertWithAPIContentController, animated: true, completion: nil)
}
}
}
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.
I'm trying to retrieve a video file I saved in the Photo Album in order to display it in a Table view controller. I have been looking for an answer but I can't seem to find one.
my function to save it to the Album looks like this:
#IBAction func saveToAlbum(_ sender: Any) {
UISaveVideoAtPathToSavedPhotosAlbum((completedMoviePath?.path)!, nil, nil, nil)
}
Seems like there is no function that could retrieve the video saved. Can someone please guide me into it?
use like this it's working for me fine in swift 3
let library = ALAssetsLibrary()
let outputURL = UserDefaults.standard.object(forKey: "url")
if library.videoAtPathIs(compatibleWithSavedPhotosAlbum: outputURL as! URL!) {
library.writeVideoAtPath(toSavedPhotosAlbum: outputURL as! URL!,completionBlock: { (assetURL:URL?, error:Error?) -> Void in
//writeVideoAtPath(toSavedPhotosAlbum: outputURL,completionBlock: { (assetURL:URL!, error:Error?) -> Void in
var title = ""
var message = ""
if error != nil {
title = "Error"
message = "Failed to save video"
} else {
title = "Success"
message = "Video saved"
}
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
})
}
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!
I'm trying to implement a forgot password feature in my app so users can enter their email in and have it reset in the database and have the new generated password emailed to them.
I believe my code should work once I fix a few minor issues but the main hurdle I'm having is how to display an alert message from the handler of another alert message.
Any idea how to do it? Either the alert message doesn't show up at all or the first one doesn't close at all.
Here is my attempt at it:
//This function will send a password reset email
func emailPassword(alertAction: UIAlertAction!) -> Void {
let textField = reset_alert.textFields![0] as UITextField
if(!textField.text!.isEmpty){
if(textField != "mik"){
let query = PFQuery(className: "_User")
let forgotten_email = textField.text
query.whereKey("email", equalTo: forgotten_email!)
query.findObjectsInBackgroundWithBlock{
(objects: [PFObject]?, error: NSError?) -> Void in
//NO ERROR//
if(error == nil){
//email in db generate random password
let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomString : NSMutableString = NSMutableString(capacity: 12)
var users_name = ""
for _ in 0...10{
let length = UInt32 (letters.length)
let rand = arc4random_uniform(length)
randomString.appendFormat("%C", letters.characterAtIndex(Int(rand)))
}
//set new password for user
if let objects = objects {
for object in objects {
object["_hashed_password"] = randomString
users_name = object["name"] as! String
//send password to email
self.mailgun.sendMessageTo("\(users_name) <\(textField)>", from: "")
self.displayAlert("SUCCESS", msg: "Check your email for your new password")
self.reset_alert.dismissViewControllerAnimated(true, completion: nil)
}
}
else{
self.reset_alert.dismissViewControllerAnimated(true, completion: nil)
self.displayAlert("ERROR", msg: "Email not registered to an account")
}
}
//ERROR//
else{
self.reset_alert.dismissViewControllerAnimated(true, completion: nil)
self.displayAlert("ERROR", msg: "Email not registered to an account") }
} //end if textfield not admin email
self.presentViewController(reset_alert, animated: true, completion: nil)
}
}//end of if textfield is empty
}
Try this extension:
typealias AlertActionBlock = (UIAlertAction) -> Void
extension UIViewController {
func flash(title title:String?, message:String?, cancelTitle:String?, actions:UIAlertAction?...) {
let b = {
let alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
let cancelBlock:AlertActionBlock = {(action:UIAlertAction) -> Void in }
let cancelAction = UIAlertAction(title: cancelTitle, style: UIAlertActionStyle.Cancel, handler: cancelBlock)
alertController.addAction(cancelAction)
for action in actions {if let action = action {alertController.addAction(action)}}
self.presentViewController(alertController, animated: true, completion: nil)
}
if NSThread.isMainThread() {
b()
} else {
dispatch_async(dispatch_get_main_queue(), b)
}
}
}
That should let you call that function from background threads or the main thread just call that function and fill in the variables
EDIT (I didn't realize you need a textfield) so try this:
func flash(title title:String?, message:String?, textFieldConfigurator:(UITextField -> Void)? = nil, cancelTitle:String?, actions:UIAlertAction?...) {
let b = { () -> Void in
let alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
if let textFieldConfigurator = textFieldConfigurator {alertController.addTextFieldWithConfigurationHandler(textFieldConfigurator)}
let cancelBlock:AlertActionBlock = {(action:UIAlertAction) -> Void in }
let cancelAction = UIAlertAction(title: cancelTitle, style: UIAlertActionStyle.Cancel, handler: cancelBlock)
alertController.addAction(cancelAction)
for action in actions {if let action = action {alertController.addAction(action)}}
self.presentViewController(alertController, animated: true, completion: nil)
}
if NSThread.isMainThread() {
b()
} else {
dispatch_async(dispatch_get_main_queue(), b)
}
}
If you need multiple text fields make it an array and iterate through it. Let me know how it goes!