Putting JSON data into an array when using Alamofire - ios

I am trying to retrieve data from my site, I am using Alamofire, how can I put that data into an array that I can use to populate my table view?
override func viewDidLoad() {
super.viewDidLoad()
Alamofire.request("http://lytestech.ga/api/lytes/get_movies/").responseJSON { response in
if let json = response.result.value {
print("JSON: \(json)") // serialized json response
let res = json as! NSDictionary
let movies = res["movies"] as! NSArray
// movieTitles = movies["movie_desc"]
let movieTitles: [String] = movies["movietitile"] as! String
print (movies)
print (movieTitles)
}
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)") // original server data as UTF8 string
}
}
}
json data
JSON: {
movies = (
{
id = 66;
"movie_desc" = "spiders bite";
movietitile = spiderman;
},
{
id = 64;
"movie_desc" = horror;
movietitile = mummy;
}
);
status = ok;
}
(
{
id = 66;
"movie_desc" = "spiders bite";
movietitile = spiderman;
},
{
id = 64;
"movie_desc" = horror;
movietitile = mummy;
}
)

Store movies in movies NSArray
var movies = NSArray()
After that in cellForRowAt method you can display data like this.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Identifier") as! YouCustomCell
let movieDetail = movies[indexPath.row] as! NSDictionary
cell.lblMovieName.text = movieDetail.value(forKey: "movietitile") as? String
return cell
}
Note: - This is just code skeleton, you can use as per your custom cell and Outlets

var movies:[Dictionary<String,AnyObject>] = [] // Makes movies array global
movies = res["movies"] // and tableview reload
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let identifier = "cell"
let cell = tableView.dequeueReusableCell(withIdentifier: identifier) ??
UITableViewCell(style: .default, reuseIdentifier: identifier)
cell.textLabel!.text = movies[indexPath.row]["movietitile"] as? String
return cell
}

func demo()
{
let str : String = "http://lytestech.ga/api/lytes/get_movies/"
let url = NSURL(string:str)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
Alamofire.request(request)
.responseString { response in
switch (response.result) {
case .Success(let JSON):
let data = JSON.dataUsingEncoding(NSUTF8StringEncoding)!
do {
let responseString = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String:AnyObject]
// print(responseString!)
self.movieName = []
self.desc = []
let arr = responseString!["movies"] as! NSArray
for j in 0..<arr.count{
let dic = arr[j] as! NSMutableDictionary
self.movieName.addObject(dic.valueForKey("movietitile")!)
self.desc.addObject(dic.valueForKey("movie_desc")!)
}
self.removeIndicator()
self.contactTable.reloadData()
} catch _ as NSError {
//print(error)
}
break
case .Failure:
print("FAILURE")
self.removeIndicator()
break
}
}
}

Convert your response Data into Dictionary
let dictionary: Dictionary? = NSKeyedUnarchiver.unarchiveObject(with: response.data) as! [String : Any]
Extract your Array from Dictionary , there is key name movies
if let arryMovies1 = dictionary["movies"] as? [[String:Any]] {
print (arryMovies1);
// Now your have your Array
// You can Populate into UItableView
// when your array is modified than you have to reload the tableData
self.arryMovies=arryMovies1
self.tableView.reloadData()
}
In your cellForRowAtIndexPath for populating in list view
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "you_cell_identifre") as! UITableCell
let dicMovie = self.arryMovies[indexPath.row] as! NSDictionary
cell.lableTitle.text = dicMovie.value(forKey: "movietitile") as? String
return cell
}
I hope this will help you

Related

Swift Firebase UITableViewCell loads before Data to populate cell is available

I am pushing data which is an array of strings to a tableview controller. These strings are "uid's" which are users in my database. With this array I make a call to firebase to extract all users and then do a match to the uid's. I am getting the correct data, yet I print out everything to make sure when the data is available and the data is available only after the tableview cell loads which causes the data to be nil causing a crash or just empty data. How can I make the data load first and then the cell so the data is available for display?
I've created functions for the data and now I have it in my viewDidLoad. Also, you'll see I have tried adding the firebase call into the Cell setup but of course that does not work.
Array of strings
var data = [String]()
viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
Database.database().reference().child("Businesses").observe(.value, with: { snapshot in
if snapshot.exists() {
self.businessUID = snapshot.value as? NSDictionary
if let dict = snapshot.value as? NSDictionary {
for item in dict {
let json = JSON(item.value)
let businessUid = json["uid"].stringValue
for uid in self.data {
if uid == businessUid {
let customerValue = self.businessUID?[uid]
self.businessDictionary = customerValue as! NSDictionary
print(self.businessDictionary)
print("Just printed the business dictionary")
}
}
}
}
} else {
print("does not exist")
}
})
}
Tableview Cell
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomerViewsSelectedBusinessesCell
print(self.businessDictionary)
print("Print the dictionary here to check the values")
let businessValues = self.businessDictionary
let uid = self.data.description
print(businessValues)
print("printed the business values")
if let dict = businessValues {
for item in dict {
let json = JSON(item.value)
let businessUid = json["uid"].stringValue
for uid in self.data {
if uid == businessUid {
let customerValue = self.businessUID?[uid]
self.businessData = customerValue as? NSDictionary
print(self.businessData)
print("Printing matching the uid values")
}
}
}
}
cell.businessName.text = businessData?["businessName"] as? String
cell.businessStreet.text = businessData?["businessStreet"] as? String
cell.businessCity.text = businessData?["businessCity"] as? String
cell.businessState.text = businessData?["businessState"] as? String
let businessProfilePicture = businessData?["profPicString"] as? String
if (businessProfilePicture!.characters.count) > 0 {
let url = URL(string: (businessProfilePicture!))
DispatchQueue.global().async {
let data = try? Data(contentsOf: url!)
DispatchQueue.main.async {
let image = UIImage(data: data!)?.potter_circle
cell.profileImage.contentMode = UIView.ContentMode.scaleAspectFill
cell.profileImage.image = image
}
}
} else {
let image = UIImage(named: "default")?.potter_circle
cell.profileImage.contentMode = UIView.ContentMode.scaleAspectFill
cell.profileImage.image = image
}
return cell
}
Here is my solution. Got it to work. Appened and used "usersArray" to get and display the data.
var data = [String]()
var usersArray = [NSDictionary?]()
override func viewDidLoad() {
super.viewDidLoad()
Database.database().reference().child("Businesses").observe(.value, with: { snapshot in
if snapshot.exists() {
self.businessUID = snapshot.value as? NSDictionary
if let dict = snapshot.value as? NSDictionary {
for item in dict {
let json = JSON(item.value)
let businessUid = json["uid"].stringValue
for uid in self.data {
if uid == businessUid {
let customerValue = self.businessUID?[uid]
self.usersArray.append(customerValue as! NSDictionary)
self.followUsersTableView.reloadData()
}
}
}
}
} else {
print("does not exist")
}
})
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.usersArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomerViewsSelectedBusinessesCell
let user : NSDictionary?
user = self.usersArray[indexPath.row]
cell.businessName.text = String(user?["businessName"] as! String)
cell.businessStreet.text = String(user?["businessStreet"] as! String)
cell.businessCity.text = String(user?["businessCity"] as! String)
cell.businessState.text = String(user?["businessState"] as! String)
let businessProfilePicture = String(user?["profPicString"] as! String)
if (businessProfilePicture.characters.count) > 0 {
let url = URL(string: (businessProfilePicture))
DispatchQueue.global().async {
let data = try? Data(contentsOf: url!)
DispatchQueue.main.async {
let image = UIImage(data: data!)?.potter_circle
cell.profileImage.contentMode = UIView.ContentMode.scaleAspectFill
cell.profileImage.image = image
}
}
} else {
let image = UIImage(named: "default")?.potter_circle
cell.profileImage.contentMode = UIView.ContentMode.scaleAspectFill
cell.profileImage.image = image
}
return cell
}

TableView doesnot show the data?

My tableView does not show the data. I am fetching the data through api and save it into separate class with initializers. But it does not the show on the tableView. How to resolve this issue. I am new to iOS. I know there is only one line of code problem somewhere.
I call api in viewDidLoad method.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
//fetch all expected visitor data
self.apiExpectedVisitor(strURL: urlViewExpectedVisitors)
self.expectedTableView.reloadData()
}
Function of API Method
func apiExpectedVisitor(strURL: String)
{
fetchedExpectedData = []
//URL
let myURL = URL(string: strURL)
//URL Request
let request = NSMutableURLRequest(url: myURL!)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Accept")
let token = "Bearer " + strToken
request.addValue(token, forHTTPHeaderField: "Authorization")
let postTask = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
print(response!)
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: [Any]] {
print("POST Method :\(json)")
DispatchQueue.main.async {
for expectedVisitors in json["expected_visitors"]!
{
let eachData = expectedVisitors as! [String: Any]
let id = eachData["id"] as! Int
let name = "\(String(describing: eachData["name"]))"
let email = "\(String(describing: eachData["email"]))"
let phone = eachData["phone"] as! String
let verification_code = "\(String(describing: eachData["expected_visitor_verification_code"]))"
let qr_code = eachData["expected_visitor_qr_code"] as? String
let isVisited = eachData["is_visited"] as! Int
let company_id = eachData["company_id"] as! Int
let purpose = "\(String(describing: eachData["purpose"]))"
let meeting_date = eachData["meeting_date"] as! String
let meeting_time = eachData["meeting_time"] as! String
let created_at = eachData["created_at"] as! String
let updated_at = eachData["updated_at"] as! String
//Date.formatter(createdDate: createdDate)
if let department_id = eachData["department_id"] as? Int, let employee_id = eachData["employee_id"] as? Int, let location_id = eachData["location_id"] as? Int, let image = eachData["image"] as? String, let duration = eachData["duration"] as? String {
fetchedExpectedData.append(FetchedAllExpectedVisitors.init(id: id, name: name, email: email, phone: phone, department_id: department_id, employee_id: employee_id, location_id: location_id, image: image, verification_code: verification_code, qr_code: qr_code!, isVisited: isVisited, company_id: company_id, purpose: purpose, meeting_date: meeting_date, meeting_time: meeting_time, duration: duration, created_at: created_at, updated_at: updated_at))
self.expectedTableView.reloadData()
}
}
}
}
} catch let error {
print(error.localizedDescription)
}
}
postTask.resume()
}
TableView DataSource and Delegate Methods
func numberOfSections(in tableView: UITableView) -> Int {
return fetchedExpectedData.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ShowExpectedCell", for: indexPath) as! ShowExpectedTVCell
cell.lblDate.text = fetchedExpectedData[indexPath.section].created_at
cell.lblVisName.text = fetchedExpectedData[indexPath.section].name
print(fetchedExpectedData[indexPath.section].name)
for i in 0..<fetchedDepttData.count {
let department_id = fetchedDepttData[i].depttID
if fetchedExpectedData[indexPath.section].department_id == department_id
{
cell.lblDeptt.text = fetchedDepttData[i].depttName
}
}
for i in 0..<fetchedEmployeeData.count {
let employee_id = fetchedEmployeeData[i].empID
if fetchedExpectedData[indexPath.section].employee_id == employee_id
{
cell.lblEmpName.text = fetchedEmployeeData[i].name
}
}
return cell
}
Check below points:-
Make sure you registered tableview cell nib and added dataSource and Delegate.
You are reloading tableview after your fetchedExpectedData array filled
Just add the below code in viewDidLoad
expectedTableView.delegate = self
expectedTableView.datasource = self
also check if you have set UITableViewDelegate , UITableViewDataSource in starting of the controller
class Yourviewcontrollername: UIViewController,UITableViewDelegate,UITableViewDataSource
{
//Rest of the code
}
Also put breakpoint in all delegate methods and see if anything hits.

Swift 3: Custom Cell not displaying data

Im receiving a JSON array from php and trying to passing data to table view. However, my tableview does not display the data.
class test1ViewController: UIViewController , UITableViewDataSource, UITableViewDelegate {
var TableData:Array< String > = Array < String >()
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return TableData.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! testTableViewCell
cell.mylabel1.text = TableData[indexPath.row]
return cell
}
func get_data_from_url(_ link:String)
{
let url:URL = URL(string: link)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "GET"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
print(data!)
self.extract_json(data!)
})
task.resume()
}
func extract_json(_ data: Data)
{
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data, options: [])
// print(json!)
}
catch
{
return
}
guard let data_list = json as? NSArray else
{
return
}
if let countries_list = json as? NSArray
{
for i in 0 ..< data_list.count
{
if let country_obj = countries_list[i] as? NSDictionary
{
if let name = country_obj["name"] as? String
{
if let age = country_obj["age"] as? String
{
TableData.append(name + age)
}
}
}
}
}
}
When the array gives initial values like
animals = ["hinno", "ali", "khalil"],
the values appear to custom cell, but when i take the data from a server and do the json conversion, nothing appears.
tableview.reloadData() any time you make changes to the array.
If reload Data of the collection or tableView doesn't work use that in Dispatch code like this
DispatchQueue.main.async {
yourTableViewName.reloadData()
}

Swift Adding objects from on array to another array correctly?

So I have 2 NSMutableArrays, one called testArray and the other called jsonArray. jsonArray gets its objects from a mysql server using json and php. Then those same objects in jsonArray are inserted in testArray. I did print(jsonArray, testArray) and what showed in the logs were this.
I also have a NSObject class called Test, if that helps..
For the jsonArray
{
testName = GreenCorn;
testStatus1 = 12;
testStatus2 = 13;
testURL = "";
id = 1;
}
For the testArray
"<CustomCellSwift.Test: 0x17414df70>"
Now I'm new to iOS Swift but I don't know if I inserted the jsonArray into testArray correctly. Here is the code I used. Also, I'm using a custom tableview and its supposed to show testArray.count, its empty cells but its showing the several rows that I have in jsonArray.
var followedArray: NSMutableArray = []
var testArray: NSMutableArray = []
var jsonArray: NSMutableArray = []
var filteredArray: NSArray = []
var isFiltered: Bool = false
// Number of Rows in Section
internal func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if !isFiltered {
if section == 0 {
return followedArray.count
}
else if section == 1 {
return testArray.count
}
}
return filteredArray.count
}
internal func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let CellIdentifier = "Cell"
var cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as! CustomCell
if cell != cell {
cell = CustomCell(style: UITableViewCellStyle.default, reuseIdentifier: CellIdentifier)
}
// Coloring TableView
myTableView.backgroundColor = UIColor.white
// Configuring the cell
var testObject: Test
print("before ifFiltered")
if !isFiltered {
if indexPath.section == 0 {
print("isFiltered if")
testObject = followedArray[indexPath.row] as! Test
cell.populateCell(testObject, isFollowed: true, indexPath: indexPath, parentView: self)
}
else if indexPath.section == 1 {
print("isFiltered if 2")
testObject = testArray[indexPath.row] as! Test
cell.populateCell(testObject, isFollowed: false, indexPath: indexPath, parentView: self)
}
}
else {
print("isFiltered else")
testObject = filteredArray[indexPath.row] as! Test
cell.populateCell(testObject, isFollowed: false, indexPath: indexPath, parentView: self)
}
return cell
}
// Retrieving Data from Server
func retrieveData() {
let getDataURL = "http://exampleip.org/json.php"
let url: NSURL = NSURL(string: getDataURL)!
do {
let data: Data = try Data(contentsOf: url as URL)
jsonArray = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSMutableArray
// Setting up testArray
let testArray: NSMutableArray = []
// Looping through jsonArray
for i in 0..<jsonArray.count {
// Create Test Object
let tID: String = (jsonArray[i] as AnyObject).object(forKey: "id") as! String
let tName: String = (jsonArray[i] as AnyObject).object(forKey: "testName") as! String
let tStatus1: String = (jsonArray[i] as AnyObject).object(forKey: "testStatus1") as! String
let tStatus2: String = (jsonArray[i] as AnyObject).object(forKey: "testStatus2") as! String
let tURL: String = (jsonArray[i] as AnyObject).object(forKey: "testURL") as! String
// Add Test Objects to Test Array
testArray.add(Test(testName: tName, andTestStatus1: tStatus1, andTestStatus2: tStatus2, andTestURL: tURL, andTestID: tID))
print("retrieveData")
print(jsonArray, testArray)
}
}
catch {
print("Error: (Retrieving Data)")
}
myTableView.reloadData()
}
Am I doing this correctly? Why does my tableview have empty cells?
First, your networking/serialization code shouldn't be in your ViewController, but this is a better way to do things:
func retrieveData() {
let getDataURL = "http://exampleip.org/json.php"
let url: NSURL = NSURL(string: getDataURL)!
do {
let data: Data = try Data(contentsOf: url as URL)
guard let jsonArray = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [[String : AnyObject]] else {
print("Error Retrieving Data")
return
}
let testArray = jsonArray.flatMap(Test.init)
// make sure the add the result in your viewController
self.myTableView.models = testArray
}
catch {
print("Error: (Retrieving Data)")
}
myTableView.reloadData()
}
extension Test {
convenience init?(with jsonDictionary: [String : AnyObject]) {
guard let tID = jsonDictionary["id"] as? String, let tName = jsonDictionary["testName"] as? String, let tStatus1 = jsonDictionary["testStatus1"] as? String,
let tStatus2 = jsonDictionary["testStatus2"] as? String, let tURL = jsonDictionary["testURL"] as? String else {
return nil
}
self(testName: tName, andTestStatus1: tStatus1, andTestStatus2: tStatus2, andTestURL: tURL, andTestID: tID)
}
}
I couldn't really test it so there may be some errors, but that should point you in the right direction.
Removing this line of code worked.
let testArray: NSMutableArray = []

Working with Tableviews

Hi I am a little new to Swift and tableviews I am working on a final project at school and I am using Alamofire to make my request and SwiftyJSON to parse through my JSON. I want to store some data that is in a [[String:String]] into my tableview cell. I keep on getting this error and can't not figure out, If anyone can point me in the right direction I would appreciate it.
var items = [[String: String]]()
var regions = ["NA", "EUW", "EUNE", "BR", "KR", "LAN", "LAS", "OCE", "RU","TR"]
override func viewDidLoad() {
super.viewDidLoad()
let pickerView = UIPickerView()
pickerView.delegate = self
pickerView.selectRow(0, inComponent: 0, animated: true)
regionPicker.inputView = pickerView
regionPicker.text = regions[0];
search.backgroundColor = UIColor.blackColor();
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
loadData("maj0r Lee Hung")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
cell.textLabel?.text = items[indexPath.row]
return cell
}
func loadData(name: String){
let escapedName = name.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
let url = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/\(escapedName!)"
Alamofire.request(.GET, url , parameters: [ "api_key":"BLAHBLAHBLAH" ])
.responseJSON { response in
switch response.result {
case .Success:
if let value = response.result.value {
let json = JSON(value)
print(json)
for (key: _, subJson: json) in json {
let id = json["id"].stringValue
let name = json["name"].stringValue
let iconID = json["profileIconId"].stringValue
let obj = ["id": id, "name": name, "iconID": iconID]
self.items.append(obj)
self.tableView.reloadData()
}
}
case .Failure(let error):
print(error)
}
}
}
In your code
cell.textLabel?.text = items[indexPath.row]
The text is expecting a string, but you are passing a dictionary. You need to take the items[indexPath.row] and extract an individual string from it.

Resources