0

Hello i have variables but gives all of them Optional(). How can i resolve them my codes under below.

Json append codes for koltuklar koltuklaridler array under below you can see

        for name in json as! [AnyObject] {

            let SeatName = name["SeatName"]
            let SeatDesignId = name["SeatDesignId"]
            self.koltuklar.append("\(SeatName)*\(SeatDesignId)*")

            if let blogs = json["SeatDetail"] as? [[String: AnyObject]] {
                for blog in blogs {

                    let TicketTypeId = blog["TicketTypeId"]
                    let TicketTypeName = blog["TicketTypeName"]
                    let Amount = blog["Amount"]

                    self.koltuklaridler.append("\(SeatDesignId)*\(TicketTypeId)*\(TicketTypeName)*\(Amount)*")


                }

            }

Under below you can see tableview inside codes ( That codes doing open koltuklar index path item after search id inside koltuklaridler and when found take some varibles from it )

var koltuklar = [""]
var koltuklaridler = [""]

if let myStrings:String! = koltuklar[indexPath.row]{

    print("\(myStrings!)")

    let myStringArrf = myStrings.componentsSeparatedByString("*")


    print("\(myStringArrf)")


    if let koltukisims:String! = String(myStringArrf[0]) {

        cell.koltukName.text = koltukisims
    }


    print(" STR - \(myStringArrf[1] as String!)")


    if let index = koltuklaridler.indexOf(myStringArrf[1] as String!) {

        let myStringdetaysecilen = koltuklaridler[index]

        print("myStringdetaysecilen \(myStringdetaysecilen)")


    }

Also my json file

[
    {
        "SeatDesignId": 16484,
        "SeatName": "A6",
        "SaloonId": 148,
        "SeatDetail": [
            {
                "TicketTypeId": 1,
                "TicketTypeName": "Okay",
                "Amount": 13
            }
        ]
    },

Output

Optional("A17")*Optional(16254)*
["Optional(\"A17\")", "Optional(16254)", ""]
STR - Optional(16254)

All variables output Optional i try everything but doesn't fix.

  • Just remove the needless type annotations (as well as the `as String!` cast). Do not annotate types at all unless the compiles tells you. – vadian Sep 01 '16 at 08:30
  • PS: In an `as` cast always the `as` takes the exclamation/question mark and never the following type. – vadian Sep 01 '16 at 08:38
  • @vadian i deleted all as String! s but same all optional ! –  Sep 01 '16 at 08:43
  • for your definition, `koltuklar` is already a `String` array, you don't have to downcast it. – Willjay Sep 01 '16 at 08:43
  • @WeiJay i deleted :String! inside myStrings and i deleted if and same output –  Sep 01 '16 at 08:45
  • How do you structure your datasource? In other words, how do your `koltuklar` come from – Willjay Sep 01 '16 at 08:47
  • Then you have declared somewhere else an optional variable which affects the output. This code is supposed to throw an error in the second line without the annotation if the array is non-optional. – vadian Sep 01 '16 at 08:47
  • @WeiJay that codes inside tableview when i use that codes top side `print("\(koltuklar[indexPath.row])")` gives me output `Optional("D8")*Optional(16680)*` –  Sep 01 '16 at 08:51
  • I added also koltuklar array append json codes top side in question –  Sep 01 '16 at 08:55
  • 1
    The problem is you already added optional strings. Whenever you use String Interpolation `"\(...)"` make sure that all strings are unwrapped. Values read from dictionaries are **always** optional. – vadian Sep 01 '16 at 09:00
  • @vadian my codes there cell.koltukName.text why ? optional ? why myStrings optional ? –  Sep 01 '16 at 09:02
  • 1
    Once again: All strings (actually everything) retrieved from a dictionary are optional by definition because you get `nil` if the key does not exist. – vadian Sep 01 '16 at 09:04
  • @vadian so what is true codes vadian ? my codes there how we can fix them ? –  Sep 01 '16 at 09:07
  • EVERYBODY EXPLAIN EVERYTHING ! BLA , BLA BUT NOBODY GIVES FIXED CODE CHANGES ! –  Sep 01 '16 at 09:13

3 Answers3

0

Your problem is that you are creating a string from values from dict without a if let statement so it returns an optional value:

for name in json as! [AnyObject] {

        if let SeatName = name["SeatName"],
           let SeatDesignId = name["SeatDesignId"] {
            self.koltuklar.append("\(SeatName)*\(SeatDesignId)*")
        }

        if let blogs = json["SeatDetail"] as? [[String: AnyObject]] {
            for blog in blogs {

                if let TicketTypeId = blog["TicketTypeId"],
                   let TicketTypeName = blog["TicketTypeName"],
                   let Amount = blog["Amount"] {
                   self.koltuklaridler.append("\(SeatDesignId)*\(TicketTypeId)*\(TicketTypeName)*\(Amount)*")
                }
            }

        }
Marco Santarossa
  • 4,058
  • 1
  • 29
  • 49
0

As mentioned in my comments, whenever you use String Interpolation "\(...)" make sure that all optional strings are unwrapped. Values read from dictionaries are always optional.

This code unwraps all optional strings

for name in json as! [[String:AnyObject]] {

  guard let SeatName = name["SeatName"] as? String,
        SeatDesignId = name["SeatDesignId"] as? Int else  {
      continue
  }
  self.koltuklar.append("\(SeatName)*\(SeatDesignId)*")

  if let blogs = json["SeatDetail"] as? [[String: AnyObject]] {
    for blog in blogs {
      if let TicketTypeId = blog["TicketTypeId"] as? Int,
           TicketTypeName = blog["TicketTypeName"]  as? String,
                   Amount = blog["Amount"]  as? Int {
        self.koltuklaridler.append("\(SeatDesignId)*\(TicketTypeId)*\(TicketTypeName)*\(Amount)*")        
      }
    }
}

Edit: I updated the casting to the actual types according to the JSON

Now declare both arrays as empty string arrays.

var koltuklar = [String]()
var koltuklaridler = [String]()

and remove the optional binding in the first line

let myStrings = koltuklar[indexPath.row]
print("\(myStrings)")
...

By the way: Your way to "serialize" the strings with asterisks and deserialize it in the table view is very, very clumsy and inefficient. Use a custom class or struct for the data records.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • i changed that codes inside my codes but tableview dont show any item nothing –  Sep 01 '16 at 09:37
  • I just edited the answer because according to the JSON some of the types are numeric (`Int`) rather than `String` – vadian Sep 01 '16 at 09:39
  • now came but have issues 1: koltuklaridler dont append any item output [""] also dont search if let index = koltuklaridler.indexOf(myStringArrf[1]) { in array –  Sep 01 '16 at 09:43
  • same print(self.koltuklaridler) gives output [""] also print("myStringdetaysecilen \(myStringdetaysecilen)") nothing –  Sep 01 '16 at 10:07
  • im trying to convert my codes to struct after i will update my question later i think you will be fix it easily. –  Sep 01 '16 at 10:42
0

There is a two way of operate optional.

  1. unwrapped using "!" but in this chances of crash if value is nil.
  2. unwrapped using term call "optional binding" using "if let" condition.
if let var = "assigned your optional variable"{
print(var)
}

You will get your variable without optional.

Ayush Yadav
  • 294
  • 5
  • 11