Pass CSV file to Swift 2 File for UI Automation Testing - swift2

Hi i am absolute beginner to the swift and Xcode tool. I am trying to Test application through UI Testing bundle introduced from Xcode 7+. I want to migrate my hardcoded data from scripts to cvs file. please help.
currently i have created a class csvScanner but it is showing Argument labels(contentsOfFile:,encoding :,error) error in code below
import Foundation
class CSVScanner {
class func debug(string:String){
print("CSVScanner: \(string)")
}
class func runFunctionOnRowsFromFile(theColumnNames:Array<String>, withFileName theFileName:String, withFunction theFunction:(Dictionary<String, String>)->()) {
if let strBundle = NSBundle.mainBundle().pathForResource(theFileName, ofType: "csv") {
var encodingError:NSError? = nil
if let fileObject = NSString(contentsOfFile: strBundle, encoding: NSUTF8StringEncoding, error: &encodingError){
var fileObjectCleaned = fileObject.stringByReplacingOccurrencesOfString("\r", withString: "\n")
fileObjectCleaned = fileObjectCleaned.stringByReplacingOccurrencesOfString("\n\n", withString: "\n")
let objectArray = fileObjectCleaned.componentsSeparatedByString("\n")
for anObjectRow in objectArray {
let objectColumns = anObjectRow.componentsSeparatedByString(",")
var aDictionaryEntry = Dictionary<String, String>()
var columnIndex = 0
for anObjectColumn in objectColumns {
aDictionaryEntry[theColumnNames[columnIndex]] = anObjectColumn.stringByReplacingOccurrencesOfString("\"", withString: "", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil)
columnIndex++
}
if aDictionaryEntry.count>1{
theFunction(aDictionaryEntry)
}else{
CSVScanner.debug("No data extracted from row: \(anObjectRow) -> \(objectColumns)")
}
}
}else{
CSVScanner.debug("Unable to load csv file from path: \(strBundle)")
if let errorString = encodingError?.description {
CSVScanner.debug("Received encoding error: \(errorString)")
}
}
}else{
CSVScanner.debug("Unable to get path to csv file: \(theFileName).csv")
}
}
}
Thanks in advance

If you are using Xcode 7+, you are also using Swift 2. Instead of passing an error pointer to the method, you need to use try.
The method signature has changed to convenience init(contentsOfFile path: String,
encoding enc: UInt) throws.
(Note: no error:.)

Related

Is there a way of producing a playground app?

Xcode newbie.(me.dumb)
First time poster.
I have the following code and it tested flawlessly in Xcode Playground(h/t D.Budd Data Science).
I want to turn the code into a MacOS app and I cannot fathom the correct Project and Settings
to do this or do I need to import the Playground into a Project and modify it?
Also this app needs to run in the background (ie, no Window/UI) as this would destroy the current window scene(MagicMirror), sort of like an Automater app can do. It would have an app icon, of course.
Thanks so much for any help.
import Cocoa
extension String{
// get the file name from string
func fileName() -> String{
return URL(fileURLWithPath: self).deletingPathExtension().lastPathComponent
}
// get the file extension from a string
func fileExtension() -> String{
return URL(fileURLWithPath: self).pathExtension
}
}
func readFile(inputFile: String) -> String{
//split the file extension and file name
let fileExtension = inputFile.fileExtension()
let fileName = inputFile.fileName()
//get the file URL
let fileURL = try! FileManager.default.url(for: .desktopDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let inputFile = fileURL.appendingPathComponent(fileName).appendingPathExtension(fileExtension)
//get the data
do{
let saveData = try String(contentsOf: inputFile)
return saveData
} catch {
return error.localizedDescription
}
}
func writeFile(outputFile: String, stringData: String){
let fileExtension = outputFile.fileExtension()
let fileName = outputFile.fileName()
//get the fileURL
let fileURL = try! FileManager.default.url(for: .desktopDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let outputFile = fileURL.appendingPathComponent(fileName).appendingPathExtension(fileExtension)
//save the data
guard let data = stringData.data(using: .utf8) else {
print("No Can Do")
return
}
do {
try data.write(to: outputFile)
print("data written: /data")
} catch {
print(error .localizedDescription)
}
let myData = readFile(inputFile: "test.txt")
writeFile(outputFile: "output.txt", stringData: myData)
}

xCode playground and writing files to Documents

I'm trying to test some sqlite database calls through XCode's playground. I start with a database in my Playground's Resources folder and try to move it to the Playgrounds Documents folder, however what happens is that a symbolic link is generated pointing back to the file within the Resources folder so I am unable to write to that file. However, If I figure out where the Documents folder is and then copy the file there by hand from the terminal everything works just fine.
So why does the file manager copy command actually create a sym link to rather than copy? And is there any way to actually make this happen? It seems to only be a problem with the Playground. copy from Resource to Documents works fine in the app itself.
some code to test within the playground...
let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)
let docsDir = dirPaths[0]
let destPath = (docsDir as NSString).appendingPathComponent("/data.sqlite")
print(destPath)
let fileMgr = FileManager.default
let srcPath = Bundle.main.path(forResource: "data", ofType:"sqlite")
// This copies the data.sqlite file from Resources to Documents
// ** However in the playground, only a symlink is generated
do {
try fileMgr.copyItem(atPath: srcPath!, toPath: destPath)
} catch let error {
print("Error (during copy): \(error.localizedDescription)")
}
Rod, It's too late but, I figure this out.
Context:
I add one playground to my project in the same workspace
To make the playground works with my project, I create a framework
I added the Store.db file to the framework target
I haven't added the Store.db to the Playground as a Resource
Swift 3
Playground
#testable import MyAppAsFramework
func copyMockDBToDocumentsFolder(dbPath: String) {
let localDBName = "Store.db"
let documentPath = dbPath / localDBName
let dbFile = Bundle(for: MyAppAsFrameworkSomeClass.self).path(forResource: localDBName.deletingPathExtension, ofType: localDBName.pathExtension)
FileManager.copyFile(dbFile, toFolderPath: documentPath)
}
copyMockDBToDocumentsFolder(dbPath: "The documents path")
Things like / copyFile(x) and the others are operator overloads and extensions
extension String {
public var pathExtension: String {
get {
return (self as NSString).pathExtension
}
}
public var deletingPathExtension: String {
get {
return (self as NSString).deletingPathExtension
}
}
public func appendingPath(_ path: String) -> String {
let nsSt = self as NSString
return nsSt.appendingPathComponent(path)
}
}
infix operator / : MultiplicationPrecedence
public func / (left: String, right: String) -> String {
return left.appendingPath(right)
}
extension FileManager {
class func copyFile(_ filePath: String?, toFolderPath: String?) -> Bool {
guard let file = filePath else { return false }
guard let toFolder = toFolderPath else { return false }
var posibleError: NSError?
do {
try FileManager.default.copyItem(atPath: file, toPath:toFolder)
} catch let error as NSError {
posibleError = error
print("CAN'T COPY \(error.localizedDescription)")
}
return posibleError == nil
}
}

Swift 3.0 NSFetchRequest error [duplicate]

In Swift 2 the following code was working:
let request = NSFetchRequest(entityName: String)
but in Swift 3 it gives error:
Generic parameter "ResultType" could not be inferred
because NSFetchRequest is now a generic type. In their documents they wrote this:
let request: NSFetchRequest<Animal> = Animal.fetchRequest
so if my result class is for example Level how should I request correctly?
Because this not working:
let request: NSFetchRequest<Level> = Level.fetchRequest
let request: NSFetchRequest<NSFetchRequestResult> = Level.fetchRequest()
or
let request: NSFetchRequest<Level> = Level.fetchRequest()
depending which version you want.
You have to specify the generic type because otherwise the method call is ambiguous.
The first version is defined for NSManagedObject, the second version is generated automatically for every object using an extension, e.g:
extension Level {
#nonobjc class func fetchRequest() -> NSFetchRequest<Level> {
return NSFetchRequest<Level>(entityName: "Level");
}
#NSManaged var timeStamp: NSDate?
}
The whole point is to remove the usage of String constants.
I think i got it working by doing this:
let request:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Level")
at least it saves and loads data from DataBase.
But it feels like it is not a proper solution, but it works for now.
The simplest structure I found that works in 3.0 is as follows:
let request = NSFetchRequest<Country>(entityName: "Country")
where the data entity Type is Country.
When trying to create a Core Data BatchDeleteRequest, however, I found that this definition does not work and it seems that you'll need to go with the form:
let request: NSFetchRequest<NSFetchRequestResult> = Country.fetchRequest()
even though the ManagedObject and FetchRequestResult formats are supposed to be equivalent.
Here are some generic CoreData methods that might answer your question:
import Foundation
import Cocoa
func addRecord<T: NSManagedObject>(_ type : T.Type) -> T
{
let entityName = T.description()
let context = app.managedObjectContext
let entity = NSEntityDescription.entity(forEntityName: entityName, in: context)
let record = T(entity: entity!, insertInto: context)
return record
}
func recordsInTable<T: NSManagedObject>(_ type : T.Type) -> Int
{
let recs = allRecords(T.self)
return recs.count
}
func allRecords<T: NSManagedObject>(_ type : T.Type, sort: NSSortDescriptor? = nil) -> [T]
{
let context = app.managedObjectContext
let request = T.fetchRequest()
do
{
let results = try context.fetch(request)
return results as! [T]
}
catch
{
print("Error with request: \(error)")
return []
}
}
func query<T: NSManagedObject>(_ type : T.Type, search: NSPredicate?, sort: NSSortDescriptor? = nil, multiSort: [NSSortDescriptor]? = nil) -> [T]
{
let context = app.managedObjectContext
let request = T.fetchRequest()
if let predicate = search
{
request.predicate = predicate
}
if let sortDescriptors = multiSort
{
request.sortDescriptors = sortDescriptors
}
else if let sortDescriptor = sort
{
request.sortDescriptors = [sortDescriptor]
}
do
{
let results = try context.fetch(request)
return results as! [T]
}
catch
{
print("Error with request: \(error)")
return []
}
}
func deleteRecord(_ object: NSManagedObject)
{
let context = app.managedObjectContext
context.delete(object)
}
func deleteRecords<T: NSManagedObject>(_ type : T.Type, search: NSPredicate? = nil)
{
let context = app.managedObjectContext
let results = query(T.self, search: search)
for record in results
{
context.delete(record)
}
}
func saveDatabase()
{
let context = app.managedObjectContext
do
{
try context.save()
}
catch
{
print("Error saving database: \(error)")
}
}
Assuming that there is a NSManagedObject setup for Contact like this:
class Contact: NSManagedObject
{
#NSManaged var contactNo: Int
#NSManaged var contactName: String
}
These methods can be used in the following way:
let name = "John Appleseed"
let newContact = addRecord(Contact.self)
newContact.contactNo = 1
newContact.contactName = name
let contacts = query(Contact.self, search: NSPredicate(format: "contactName == %#", name))
for contact in contacts
{
print ("Contact name = \(contact.contactName), no = \(contact.contactNo)")
}
deleteRecords(Contact.self, search: NSPredicate(format: "contactName == %#", name))
recs = recordsInTable(Contact.self)
print ("Contacts table has \(recs) records")
saveDatabase()
This is the simplest way to migrate to Swift 3.0, just add <Country>
(tested and worked)
let request = NSFetchRequest<Country>(entityName: "Country")
Swift 3.0 This should work.
let request: NSFetchRequest<NSFetchRequestResult> = NSManagedObject.fetchRequest()
request.entity = entityDescription(context)
request.predicate = predicate
I also had "ResultType" could not be inferred errors. They cleared once I rebuilt the data model setting each entity's Codegen to "Class Definition". I did a brief writeup with step by step instructions here:
Looking for a clear tutorial on the revised NSPersistentContainer in Xcode 8 with Swift 3
By "rebuilt" I mean that I created a new model file with new entries and attributes. A little tedious, but it worked!
What worked best for me so far was:
let request = Level.fetchRequest() as! NSFetchRequest<Level>
I had the same issue and I solved it with the following steps:
Select your xcdatamodeld file and go to the Data Model Inspector
Select your first Entity and go to Section class
Make sure that Codegen "Class Definition" is selected.
Remove all your generated Entity files. You don't need them anymore.
After doing that I had to remove/rewrite all occurences of fetchRequest as XCode seem to somehow mix up with the codegenerated version.
HTH
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
func loadItemsCategory() {
let request: NSFetchRequest<Category> = Category.fetchRequest()
do {
categoryArray = try context.fetch(request)
} catch {
print(error)
}
tableView.reloadData()
}

Append swift 2.0 and xcode 7 [duplicate]

I already have read Read and write data from text file
I need to append the data (a string) to the end of my text file.
One obvious way to do it is to read the file from disk and append the string to the end of it and write it back, but it is not efficient, especially if you are dealing with large files and doing in often.
So the question is "How to append string to the end of a text file, without reading the file and writing the whole thing back"?
so far I have:
let dir:NSURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.CachesDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask).last as NSURL
let fileurl = dir.URLByAppendingPathComponent("log.txt")
var err:NSError?
// until we find a way to append stuff to files
if let current_content_of_file = NSString(contentsOfURL: fileurl, encoding: NSUTF8StringEncoding, error: &err) {
"\(current_content_of_file)\n\(NSDate()) -> \(object)".writeToURL(fileurl, atomically: true, encoding: NSUTF8StringEncoding, error: &err)
}else {
"\(NSDate()) -> \(object)".writeToURL(fileurl, atomically: true, encoding: NSUTF8StringEncoding, error: &err)
}
if err != nil{
println("CANNOT LOG: \(err)")
}
Here's an update for PointZeroTwo's answer in Swift 3.0, with one quick note - in the playground testing using a simple filepath works, but in my actual app I needed to build the URL using .documentDirectory (or which ever directory you chose to use for reading and writing - make sure it's consistent throughout your app):
extension String {
func appendLineToURL(fileURL: URL) throws {
try (self + "\n").appendToURL(fileURL: fileURL)
}
func appendToURL(fileURL: URL) throws {
let data = self.data(using: String.Encoding.utf8)!
try data.append(fileURL: fileURL)
}
}
extension Data {
func append(fileURL: URL) throws {
if let fileHandle = FileHandle(forWritingAtPath: fileURL.path) {
defer {
fileHandle.closeFile()
}
fileHandle.seekToEndOfFile()
fileHandle.write(self)
}
else {
try write(to: fileURL, options: .atomic)
}
}
}
//test
do {
let dir: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last! as URL
let url = dir.appendingPathComponent("logFile.txt")
try "Test \(Date())".appendLineToURL(fileURL: url as URL)
let result = try String(contentsOf: url as URL, encoding: String.Encoding.utf8)
}
catch {
print("Could not write to file")
}
Thanks PointZeroTwo.
You should use NSFileHandle, it can seek to the end of the file
let dir:NSURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.CachesDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask).last as NSURL
let fileurl = dir.URLByAppendingPathComponent("log.txt")
let string = "\(NSDate())\n"
let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
if NSFileManager.defaultManager().fileExistsAtPath(fileurl.path!) {
var err:NSError?
if let fileHandle = NSFileHandle(forWritingToURL: fileurl, error: &err) {
fileHandle.seekToEndOfFile()
fileHandle.writeData(data)
fileHandle.closeFile()
}
else {
println("Can't open fileHandle \(err)")
}
}
else {
var err:NSError?
if !data.writeToURL(fileurl, options: .DataWritingAtomic, error: &err) {
println("Can't write \(err)")
}
}
A variation over some of the posted answers, with following characteristics:
based on Swift 5
accessible as a static function
appends new entries to the end of the file, if it exists
creates the file, if it doesn't exist
no cast to NS objects (more Swiftly)
fails silently if the text cannot be encoded or the path does not exist
class Logger {
static var logFile: URL? {
guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil }
let formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
let dateString = formatter.string(from: Date())
let fileName = "\(dateString).log"
return documentsDirectory.appendingPathComponent(fileName)
}
static func log(_ message: String) {
guard let logFile = logFile else {
return
}
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss"
let timestamp = formatter.string(from: Date())
guard let data = (timestamp + ": " + message + "\n").data(using: String.Encoding.utf8) else { return }
if FileManager.default.fileExists(atPath: logFile.path) {
if let fileHandle = try? FileHandle(forWritingTo: logFile) {
fileHandle.seekToEndOfFile()
fileHandle.write(data)
fileHandle.closeFile()
}
} else {
try? data.write(to: logFile, options: .atomicWrite)
}
}
}
Here is a way to update a file in a much more efficient way.
let monkeyLine = "\nAdding a šŸµ to the end of the file via FileHandle"
if let fileUpdater = try? FileHandle(forUpdating: newFileUrl) {
// Function which when called will cause all updates to start from end of the file
fileUpdater.seekToEndOfFile()
// Which lets the caller move editing to any position within the file by supplying an offset
fileUpdater.write(monkeyLine.data(using: .utf8)!)
// Once we convert our new content to data and write it, we close the file and thatā€™s it!
fileUpdater.closeFile()
}
Here's a version for Swift 2, using extension methods on String and NSData.
//: Playground - noun: a place where people can play
import UIKit
extension String {
func appendLineToURL(fileURL: NSURL) throws {
try self.stringByAppendingString("\n").appendToURL(fileURL)
}
func appendToURL(fileURL: NSURL) throws {
let data = self.dataUsingEncoding(NSUTF8StringEncoding)!
try data.appendToURL(fileURL)
}
}
extension NSData {
func appendToURL(fileURL: NSURL) throws {
if let fileHandle = try? NSFileHandle(forWritingToURL: fileURL) {
defer {
fileHandle.closeFile()
}
fileHandle.seekToEndOfFile()
fileHandle.writeData(self)
}
else {
try writeToURL(fileURL, options: .DataWritingAtomic)
}
}
}
// Test
do {
let url = NSURL(fileURLWithPath: "test.log")
try "Test \(NSDate())".appendLineToURL(url)
let result = try String(contentsOfURL: url)
}
catch {
print("Could not write to file")
}
In order to stay in the spirit of #PointZero Two.
Here an update of his code for Swift 4.1
extension String {
func appendLine(to url: URL) throws {
try self.appending("\n").append(to: url)
}
func append(to url: URL) throws {
let data = self.data(using: String.Encoding.utf8)
try data?.append(to: url)
}
}
extension Data {
func append(to url: URL) throws {
if let fileHandle = try? FileHandle(forWritingTo: url) {
defer {
fileHandle.closeFile()
}
fileHandle.seekToEndOfFile()
fileHandle.write(self)
} else {
try write(to: url)
}
}
}
Update: I wrote a blog post on this, which you can find here!
Keeping things Swifty, here is an example using a FileWriter protocol with default implementation (Swift 4.1 at the time of this writing):
To use this, have your entity (class, struct, enum) conform to this protocol and call the write function (fyi, it throws!).
Writes to the document directory.
Will append to the text file if the file exists.
Will create a new file if the text file doesn't exist.
Note: this is only for text. You could do something similar to write/append Data.
import Foundation
enum FileWriteError: Error {
case directoryDoesntExist
case convertToDataIssue
}
protocol FileWriter {
var fileName: String { get }
func write(_ text: String) throws
}
extension FileWriter {
var fileName: String { return "File.txt" }
func write(_ text: String) throws {
guard let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
throw FileWriteError.directoryDoesntExist
}
let encoding = String.Encoding.utf8
guard let data = text.data(using: encoding) else {
throw FileWriteError.convertToDataIssue
}
let fileUrl = dir.appendingPathComponent(fileName)
if let fileHandle = FileHandle(forWritingAtPath: fileUrl.path) {
fileHandle.seekToEndOfFile()
fileHandle.write(data)
} else {
try text.write(to: fileUrl, atomically: false, encoding: encoding)
}
}
}
All answers (as of now) recreate the FileHandle for every write operation. This may be fine for most applications, but this is also rather inefficient: A syscall is made, and the filesystem is accessed each time you create the FileHandle.
To avoid creating the filehandle multiple times, use something like:
final class FileHandleBuffer {
let fileHandle: FileHandle
let size: Int
private var buffer: Data
init(fileHandle: FileHandle, size: Int = 1024 * 1024) {
self.fileHandle = fileHandle
self.size = size
self.buffer = Data(capacity: size)
}
deinit { try! flush() }
func flush() throws {
try fileHandle.write(contentsOf: buffer)
buffer = Data(capacity: size)
}
func write(_ data: Data) throws {
buffer.append(data)
if buffer.count > size {
try flush()
}
}
}
// USAGE
// Create the file if it does not yet exist
FileManager.default.createFile(atPath: fileURL.path, contents: nil)
let fileHandle = try FileHandle(forWritingTo: fileURL)
// Seek will make sure to not overwrite the existing content
// Skip the seek to overwrite the file
try fileHandle.seekToEnd()
let buffer = FileHandleBuffer(fileHandle: fileHandle)
for i in 0..<count {
let data = getData() // Your implementation
try buffer.write(data)
print(i)
}

Swift 2.0: Could not find overload. Need Explanation

I have the following code in my program.
var detailItem: RSSItem? {
didSet {
self.configureView()
}
}
func configureView() {
if let item: RSSItem = self.detailItem
{
if let webView = self.itemWebView
{
if let templateURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("template", ofType: "html")!)?
{
if var template = NSString(contentsOfURL: templateURL, encoding: NSUTF8StringEncoding)?
{
if let title = item.title
{
template = template.stringByReplacingOccurrencesOfString("###TITLE###", withString: title)
}
if let content = item.content
{
template = template.stringByReplacingOccurrencesOfString("###CONTENT###", withString: content)
}
else if let description = item.itemDescription
{
template = template.stringByReplacingOccurrencesOfString("###CONTENT###", withString: description)
}
if let date = item.pubDate
{
var formatter = NSDateFormatter()
formatter.dateFormat = "MMM dd, yyyy"
template = template.stringByReplacingOccurrencesOfString("###DATE###", withString: formatter.stringFromDate(date))
}
if let author = item.author
{
template = template.stringByReplacingOccurrencesOfString("###AUTHOR###", withString: author)
}
webView.loadHTMLString(template, baseURL: nil)
}
}
else
{
if let content = item.content
{
webView.loadHTMLString(content, baseURL: nil)
}
else if let description = item.itemDescription
{
webView.loadHTMLString(description, baseURL: nil)
}
}
}
}
}
On the line:
if let templateURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("template", ofType: "html")!)?
I get the following error:
-Could not find an overload for 'pathForResource' that accepts the supplied arguments
Can someone explain this error to me and maybe suggest a solution. I have been reading through various searches on Google but can't quite seem to get what I need.
Thanks in advance.
NSURL(fileURLWithPath:) is now return a NSURL so just don't use if let here.
#available(iOS 2.0, *)
init(fileURLWithPath path: String, isDirectory isDir: Bool)
init(fileURLWithPath path: String) // Better to use initFileURLWithPath:isDirectory: if you know if the path is a directory vs non-directory, as it saves an i/o.
#available(iOS 2.0, *)
class func fileURLWithPath(path: String, isDirectory isDir: Bool) -> NSURL
class func fileURLWithPath(path: String) -> NSURL // Better to use fileURLWithPath:isDirectory: if you know if the path is a directory vs non-directory, as it saves an i/o.
for the line: if var template = NSString(contentsOfURL: templateURL, encoding: NSUTF8StringEncoding)?
Its decleration is:
convenience init(contentsOfURL url: NSURL, encoding enc: UInt) throws
convenience init(contentsOfFile path: String, encoding enc: UInt) throws
So it not returns optional NSString either, so you cannot use if let again. You have to use do-try-catch here.
Apple's document about this:
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html#//apple_ref/doc/uid/TP40014097-CH42-ID508
Also, you should use multiple unwrapping optional:
if let x = OptionalX, y = OptionalY { ... }
Your code is a pyramid of doom :)

Resources