0

I'm trying to create an app that returns Multi-up table with many data but I think I would need a completion handler in here.

// object data :

import Foundation

class  RepoSwiftyJSON:NSObject {

   let _userId:String!
   let _title:String!

   init(userid:String , title:String){
      self._userId = userid
      self._title = title  
   }
}

TableViewController

import UIKit
import Alamofire
import SwiftyJSON

class TableViewController: UITableViewController {


   var parkData:[JSON] = []
   var aryId = [RepoSwiftyJSON]()

   func getJSONData() {
       let url = "http://jsonplaceholder.typicode.com/posts/"

       Alamofire.request(.GET,url).responseJSON {response in
           guard let data = response.result.value else {
               let error = response.result.error

               let alertController = UIAlertController(title: "Error", message:error?.localizedDescription, preferredStyle: .Alert)
               let okAction = UIAlertAction(title: "Retry", style: .Default, handler: { (alert:UIAlertAction) -> Void in
                      UIApplication.sharedApplication().networkActivityIndicatorVisible = true
                      self.getJSONData()
                      alertController.dismissViewControllerAnimated(true, completion: {})
               })

               alertController.addAction(okAction)
               self.presentViewController(alertController, animated: true, completion: {})
               UIApplication.sharedApplication().networkActivityIndicatorVisible = false
               return
           }

           let json = JSON(data)
           self.parkData = json.array!

           for key in self.parkData{
              let DataArray:RepoSwiftyJSON = RepoSwiftyJSON ()
              let userId = key["userId"].intValue
              let title = key["title"].string
              DataArray._userId = userId
              DataArray._title = title
              self.aryId.append(DataArray)
           }
           self.showJSONData()
      } 
   }

   func showJSONData() {
      //println(parkData)
      tableView.reloadData()
   }

   override func viewDidLoad() {
     super.viewDidLoad()
     getJSONData()
   }


   // MARK: - Table view data source

   override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
      return 1
   }

   override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

       if let numberOfRows: Int = self.aryId.count {
          return numberOfRows
       } else {
          return 0
       }    
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
       let cell = tableView.dequeueReusableCellWithIdentifier("masterCell", forIndexPath: indexPath) 

       let rowData:JSON = aryId[indexPath.row]
       cell.textLabel?.text = rowData._title
       cell.detailTextLabel?.text = String(rowData._userId)
       print(rowData)
       return cell
    }

but When I run the app I get the following error:

Missing argument for parameter 'userid' 

In the line call line let DataArray:RepoSwiftyJSON = RepoSwiftyJSON ()

and

Cannot subscript a value of type '[RepoSwiftyJSON]' 

In the line let rowData:JSON = aryId[indexPath.row]

What I'm doing wrong?

Victor Sigler
  • 23,243
  • 14
  • 88
  • 105
phantom
  • 112
  • 8

1 Answers1

0

Let's fix the issues for parts:

First Error:

According to Apple:

Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state.

You can set an initial value for a stored property within an initializer, or by assigning a default property value as part of the property’s definition.

You're trying to use the default init method in the class RepoSwiftyJSON that inherits from NSObject, it's not recommend use the ! operator to explicit say to the compiler that the object going to have a value in runtime. So one option to solve your problem is use convenience initializer like in the following way:

class RepoSwiftyJSON: NSObject {

   let _userId: String
   let _title: String

   init(userid:String , title:String){
      self._userId = userid
      self._title = title
   }

   override convenience init() {
     self.init(userid: "a", title: "b")
   }
}

let DataArray: RepoSwiftyJSON = RepoSwiftyJSON()
DataArray._title // a
DataArray._userId // b

In the above way you override the default init of the class NSObject and mark it as convenience to allow to call the another init(userid:String , title:String) inside the default init method.

There are many ways of solve your first error, the above is just one.

Second Error:

If we check the variable aryId in his definition :

var aryId = [RepoSwiftyJSON]()

It's an array of RepoSwiftyJSON, and in your following line:

let rowData: JSON = aryId[indexPath.row]

You're trying to assign an element of type RepoSwiftyJSON returned by the above line to another of type JSON and it's not correct.

EDIT:

You can create a JSON using the following function:

let jsonObject: [AnyObject] = [
   ["name": "John", "age": 21],
   ["name": "Bob", "age": 35],
]

func createJSON(value: AnyObject) -> String {

   let options = NSJSONWritingOptions.PrettyPrinted

   guard NSJSONSerialization.isValidJSONObject(value) else {
      return ""
   }
    
   do {
       let data = try NSJSONSerialization.dataWithJSONObject(value, options: options)
    
       if let string = NSString(data: data, encoding: NSUTF8StringEncoding) {
          return string as String
       }
   } catch let error {
       print("\(error)")
   }
   return ""
}


let json = createJSON(jsonObject)

and you will see :

[
  {
    "age" : 21,
    "name" : "John"
  },
  {
    "age" : 35,
    "name" : "Bob"
  }
]

I hope this help you.

Community
  • 1
  • 1
Victor Sigler
  • 23,243
  • 14
  • 88
  • 105