1

In my app, i want to fetch data from FMDB database and that data i want to send to watch. But the problem is that when the data is fetched, it doesn't show the actual data in console like ticket_type = Movie, time = 11:42 p.m. Instead it shows only memory address result.

The source code for my TicketData is below

class TicketData: NSObject {
var field1: String?
var field2: String?
var field3: String?
var field4: String?

override init() {
    super.init()
}

convenience init(field1: String, field2: String, field3: String, field4: String) {
   self.init()

        self.field1 = field1
        self.field2 = field2
        self.field3 = field3
        self.field4 = field4

}

}

The screenshot for my app is screenshot for my app image

My source code is below

class TicketDetailViewController: UIViewController, WCSessionDelegate {

var databasePath = NSString()
var holding_Ticket_category: String = ""
var holding_Image: UIImage?
var hold_ticketName: String = ""
var hold_ticketDate: String = ""
var hold_ticketTime: String = ""
var session: WCSession!
var ticketDataArray:[TicketData] = []


@IBOutlet weak var ticket_grey: UIImageView!
@IBOutlet weak var cropped_frame: UIImageView!
@IBOutlet weak var display_image: UIImageView!
@IBOutlet weak var ticket_type_name: UILabel!
@IBOutlet weak var ticket_date: UILabel!
@IBOutlet weak var ticket_time: UILabel!
@IBOutlet weak var ticket_category: UILabel!


override func viewDidLoad()
{
    super.viewDidLoad()

    if WCSession.isSupported(){
        self.session  = WCSession.defaultSession()
        self.session.delegate = self
        self.session.activateSession()
    }

    display_image.image = holding_Image
    ticket_type_name.text = hold_ticketName
    ticket_date.text = hold_ticketDate
    ticket_time.text = hold_ticketTime
    ticket_category.text = holding_Ticket_category

    let filemgr =  NSFileManager.defaultManager()
    let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    let docsDir = dirPaths[0]
    var ticketDB: FMDatabase

    databasePath = (docsDir as NSString).stringByAppendingPathComponent("ticket_Pass.sqlite")


    if !filemgr.fileExistsAtPath(databasePath as String)
    {

        ticketDB = FMDatabase(path: databasePath as String)
        if ticketDB.open()
        {

            let sql_stmt = "CREATE TABLE IF NOT EXISTS TICKET (ID INTEGER PRIMARY KEY AUTOINCREMENT, IMAGE TEXT, TICKET_CATEGORY TEXT, TICKET_TYPE TEXT, DATE TEXT, TIME TEXT)"
            if !ticketDB.executeStatements(sql_stmt)
            {
                print("Error: \(ticketDB.lastErrorMessage())")
            }
            ticketDB.close()
        } else
        {

            print("Error: \(ticketDB.lastErrorMessage())")
        }
    }
}

@IBAction func addTickets(sender: UIButton) {

    let ticketDB = FMDatabase(path: databasePath as String)
    if ticketDB.open()
    {

            let insertSQL = "INSERT INTO TICKET (image, ticket_category, ticket_type, date, time) VALUES ('\(display_image.image!)', '\(ticket_category.text!)', '\(ticket_type_name.text!)', '\(ticket_date.text!)', '\(ticket_time.text!)')"

            let result = ticketDB.executeUpdate(insertSQL,withArgumentsInArray: nil)

            if !result
            {

                print("Error: \(ticketDB.lastErrorMessage())")

            } else
            {

                let alt = PMAlertController(title: "Success!", description: "Your data is saved to Database!", image: UIImage(named: ""), style: .Alert)

                alt.addAction(PMAlertAction(title: "OK!", style: .Default, action: { (ACTION) -> Void in

                         self.navigationController?.popToRootViewControllerAnimated(true)

                }))

                        self.presentViewController(alt, animated: true, completion: nil)
                        print(databasePath)


           }
    }
}


@IBAction func deleteTickets(sender: UIButton) {
    let alt = PMAlertController(title: "Delete Ticket Details!", description: "Are you sure?", image: UIImage(named: ""), style: .Alert)

    alt.addAction(PMAlertAction(title: "Cancel", style: PMAlertActionStyle.Default, action: { (ACTION) -> Void in

        self.dismissViewControllerAnimated(true, completion: nil)

    }))
    alt.addAction(PMAlertAction(title: "OK", style: PMAlertActionStyle.Default, action: { (ACTION) -> Void in

        self.navigationController?.popToRootViewControllerAnimated(true)
    }))
    self.presentViewController(alt, animated: true, completion: nil)
}


@IBAction func sendToWatch(sender: AnyObject) {


    let ticketDB = FMDatabase(path: databasePath as String)
    if ticketDB.open()
    {

        let insertSQL = "INSERT INTO TICKET (image, ticket_category, ticket_type, date, time) VALUES ('\(display_image.image!)', '\(ticket_category.text!)', '\(ticket_type_name.text!)', '\(ticket_date.text!)', '\(ticket_time.text!)')"

        let result = ticketDB.executeUpdate(insertSQL,withArgumentsInArray: nil)

        if !result
        {

            print("Error: \(ticketDB.lastErrorMessage())")

        } else
        {

            let alt = PMAlertController(title: "Success!", description: "Your data is saved to Database!", image: UIImage(named: ""), style: .Alert)

            alt.addAction(PMAlertAction(title: "OK!", style: .Default, action:
                { (ACTION) -> Void in

                    let ticketDB = FMDatabase(path: self.databasePath as String)
                    if ticketDB.open()
                    {

                        let querySQL = "SELECT * FROM TICKET"

                        let result: FMResultSet? = ticketDB.executeQuery(querySQL, withArgumentsInArray: nil)

                        if let result = result
                        {

                           var ticketData = TicketData()
                            while (result.next() == true)
                            {
                                let image = result.stringForColumn("image")
                                let ticket_category = result.stringForColumn("ticket_category")
                                let ticket_type = result.stringForColumn("ticket_type")
                                let date = result.stringForColumn("date")
                                let time = result.stringForColumn("time")
                                ticketData = TicketData(field1: ticket_category!, field2: ticket_type!, field3: date!, field4: time!, field5: image!)
                                 self.ticketDataArray.append(ticketData)


                            }
                        print("Data: \(result.resultDictionary())")


                            }


                       }else
                       {
                            print("Error: \(ticketDB.lastErrorMessage())")

                       }

                    ticketDB.close()


                    }

            }))

            self.presentViewController(alt, animated: true, completion: nil)
            print(databasePath)

        }
    }
Nishant Narola
  • 255
  • 3
  • 18
  • use result.resultDictionary and extract values from that dictionary by keys. i think this will help – Mahesh Agrawal Aug 24 '16 at 05:06
  • The result i get in console is below: 2016-08-24 10:23:07.294 WearWatch[807:32340] CUICatalog: Invalid asset name supplied: /Users/apple/Library/Developer/CoreSimulator/Devices/CE972FAB-70AD-47EF-9805-A2B94EDFD07D/data/Containers/Data/Application/7F7397DA-CBDC-4973-A8F5-E1EE3712E45F/Documents/ticket_Pass.sqlite Data: Data: Data: Data: Data: – Nishant Narola Aug 24 '16 at 05:06
  • how do i do it as i am new to ios development. Can u write source – Nishant Narola Aug 24 '16 at 05:10
  • what i can see is you are providing wrong path of database file . check if the file exists at the path or not. you have already written code. we can debug and solve the problem – Mahesh Agrawal Aug 24 '16 at 05:12
  • @MaheshAgrawala if he was providing the wrong database path, his statement FMDatabase(path: self.databasePath as String) itself would have failed. He is able to print the print("Data: \(ticketData)"), which means that the DB operations are happening. – iamyogish Aug 24 '16 at 05:14

1 Answers1

2

The ticketData is an object and you're trying to print an object using,

print("Data: \(ticketData)")

Whenever we try to print an object, always the object's memory address will be printed and not the object's properties. If you want to print the object properties, print it one by one like,

print("Data: \(ticketData.ticket_type)")

and so on. If you want to print everything at one shot, what you could do is you can get an dictionary object from the resultSet and print it.

print("Data:\(resultSet.resultDictionary())")

Edit: How to get the last value of the result set.

if let result = result {

var ticketData = TicketData()
var latestTicketDict = [String: AnyObject]()

while (result.next() == true) {
    let image = result.stringForColumn("image")
    let ticket_category = result.stringForColumn("ticket_category")
    let ticket_type = result.stringForColumn("ticket_type")
    let date = result.stringForColumn("date")
    let time = result.stringForColumn("time")
    ticketData = TicketData(field1: ticket_category!, field2: ticket_type!, field3: date!, field4: time!, field5: image!)
    self.ticketDataArray.append(ticketData)
    latestTicketDict = result.resultDictionary()
}

print("Data: \(latestTicketDict)")

}

Update: Also I would recommend you to go through the FMDB documentation on their github page and study some tutorials on FMDB to write more efficient DB operations. Also don't close the database and open the database for every db operation as the creator of the FMDB says When to close SQLite database (using FMDB) -

"Keep it open unless you change your schema. That's the only reason to close it, and constantly re-opening it is a little hit on performance / battery life."

Also I recommend you to take a look at FMDatabaseQueue.

Hope this Helps.

Community
  • 1
  • 1
iamyogish
  • 2,372
  • 2
  • 23
  • 40
  • thanks it helped but it prints all the entry. What if i want latest entry only printed – Nishant Narola Aug 24 '16 at 05:21
  • You mean the last dictionary which will be the latest dictionary ? – iamyogish Aug 24 '16 at 05:25
  • If you want to print the latest or last row, you need to declare the ticketData variable before while (result.next() == true) and need to assign the value to the ticketData inside the while loop. Then outside the while loop you need to print whatever the properties you want from ticketData. – iamyogish Aug 24 '16 at 05:28
  • actually my TicketData.swift file is NSObject. so how can i do it – Nishant Narola Aug 24 '16 at 05:37
  • It doesn't matter if your model is NSObject or not, you can still print the properties like print("Data: \(ticketData.ticket_type)") and so on. But if you want to print the last row, as I said in previous comment, you need to declare the ticketObject outside while loop and print it after while loop finishes. – iamyogish Aug 24 '16 at 05:41
  • I have updated my select query code but i am getting this error: 2016-08-24 12:11:17.066 WearWatch[1186:67976] CUICatalog: Invalid asset name supplied: /Users/apple/Library/Developer/CoreSimulator/Devices/CE972FAB-70AD-47EF-9805-A2B94EDFD07D/data/Containers/Data/Application/76B2301D-785D-482E-99CA-54C48C5ACE36/Documents/ticket_Pass.sqlite 2016-08-24 12:11:18.345 WearWatch[1186:67976] Warning: There seem to be no columns in this set. Data: nil – Nishant Narola Aug 24 '16 at 06:43
  • The problem is in this line: print("Data: \(result.resultDictionary())") when this line is executed the resultSet would already be nil. Please look at my answer for more info on how to take the latest value. – iamyogish Aug 24 '16 at 07:11
  • @NishantNarola , If this answer is correct for you then up vote and accept it! Because they are spend time for your problem. if you not do this people will hate to answer your questions. – Rajamohan S Aug 28 '16 at 02:07