How to get data from a CSV in swift when using UIDocumentPickerViewController - ios

I cannot find a way to import data from a CSV file. I want the data to be loading into an array.
I have tried Googling this but nothing I find seems to work for my case
This is my UIDocumentPickerViewController.
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
let urlst = "\(urls)"
if urlst.fileExtension() == "csv]" || urlst.fileExtension() == "csv" {
// Start Import Action From CSV File
} else {
let alert = UIAlertController(title: "An Error Occured!", message: "The file you were trying to inport is not supported. Only csv is support.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default , handler: nil))
alert.addAction(UIAlertAction(title: "Try Again", style: .default , handler: { (UIAlertAction) in
self.toImport()
}))
self.present(alert, animated: true, completion: nil)
}
}
My expected result is to get the csv file that the user selected using the UIDocumentPickerViewController and then importing it into an array or more then one. But I cannot find a way to make this work.

I finally found the solution to my problem. Here is the code:
let path = url.path
let importer = CSVImporter<exportDataImport>(path: path)
importer.startImportingRecords { recordValues -> exportDataImport in
return exportDataImport(name: recordValues[0], pricePer: recordValues[2], amount: recordValues[1], isComplte: recordValues[4], Qty: recordValues[3])
}.onFinish { importedRecords in
var tempArray = [exportDataImport]()
for record in importedRecords {
tempArray.append(record)
}
if tempArray.count > 0 {
tempArray.removeFirst(1)
self.importArray = tempArray
self.startImport()
}
}

Related

Writing a conditional statement for empty UITableView

The following function below is displaying an alert if no selections are made in UITableView.
But I do not want the alert to come up when the TableView has no records. How can this be done?
Work so far:
#IBAction func onTapNextButton(_ sender: UIBarButtonItem) {
guard let selectedIndexPaths = tableView.indexPathsForSelectedRows, !selectedIndexPaths.isEmpty else {
//Show Alert here...
let alert = UIAlertController(title: "Alert..!!", message: "You must select atleast 1 row before proceeding.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
return
}
}
First check if the data source array is not empty, replace dataSourceArray with the real name
guard !dataSourceArray.isEmpty else { return }
guard let selectedIndexPaths = tableView.indexPathsForSelectedRows,
!selectedIndexPaths.isEmpty else {
let alert ...
Whatever the object is that you're using as your data source (I'm assuming it's an array), check to see if that object (array) has zero elements. So, for example, something like:
//tableViewData should be the name of the array you're using as your data source
if tableViewData.isEmpty {
return
}
That way if there are no rows, you exit the function, and it won't display the alert.
// this is one way of checking if the tableView is empty
#IBAction func onTapNextButton(_ sender: UIBarButtonItem) {
if tableView.visibleCells.isEmpty {
//table view is empty: do something
} else {
guard let selectedIndexPaths = tableView.indexPathsForSelectedRows, !selectedIndexPaths.isEmpty else {
//Show Alert here...
let alert = UIAlertController(title: "Alert..!!", message: "You must select atleast 1 row before proceeding.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
return
}
}
}
***** Hope you like it *****

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.

Retrieving MP4 Video File Stored in Photo Library

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)
})
}

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
})
}

Error handling with UIAlertController

I have a UIAlertController with a textfield that allows users to type in a title to name a file before sending the data to the server. However, the backend could reject the file for a couple reasons and an error needs to be displayed. How can I display the error I get back from the server in the same alert controller where I entered the file name?
class FileController: UIViewController
{
var alertController: UIAlertController?
func savePressed()
{
createAlert()
}
func createAlert()
{
self.alertController = UIAlertController(title: "Save", message: "Name your file.", preferredStyle: .Alert)
let saveAsPublicAction = UIAlertAction(title: "Make Public", style: .Default) { (_) in
let fileTitle = self.alertController!.textFields![0] as UITextField
if fileTitle.text != ""
{
self.initiateSave(fileTitle.text!, share: true)
}
}
let saveAsPrivateAction = UIAlertAction(title: "Make Private", style: .Default) { (_) in
let fileTitle = self.alertController!.textFields![0] as UITextField
if fileTitle.text != ""
{
self.initiateSave(fileTitle.text!, share: false)
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (_) in }
self.alertController!.addTextFieldWithConfigurationHandler { (textField) in
NSNotificationCenter.defaultCenter().addObserverForName(UITextFieldTextDidChangeNotification, object: textField, queue: NSOperationQueue.mainQueue()) { (notification) in
saveAsPrivateAction.enabled = textField.text != ""
saveAsPublicAction.enabled = textField.text != ""
}
}
self.alertController!.addAction(saveAsPublicAction)
self.alertController!.addAction(saveAsPrivateAction)
self.alertController!.addAction(cancelAction)
self.presentViewController(self.alertController!, animated: true, completion: nil)
}
}
func initiateSave(title:String?, share: Bool?)
{
//package file
initiatePost()
}
func initiatePost()
{
//Send file data to server. Receive any errors and handle
}
On your server you can add more logic to send JSON data with that information.
For example:
{
"success": true,
"message": "Data received sucessfully"
}
If The request was successful, if not:
{
"success": false,
"message": "There is an error"
}
So when you parse that JSON you would check if success is false, and display the error message inside of the message key.

Resources