Swift PickerView does not show array elements - arrays

My "picker2" pickerview does not show data from "modelArray" array. When I dup the array I have data in it. But no data shown in pickerview at all.
I did everything on mind and did my research how to do it. But no success.
Any help will be highly appreciated :)
import UIKit
class MakeViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var txt_make: UITextField!
#IBOutlet weak var txt_model: UITextField!
var makeArray = [String]()
var modelArray = [String]()
var picker = UIPickerView()
var picker2 = UIPickerView()
var numberOfRowsMake = 0
var numberOfRowsModel = 0
override func viewDidLoad() {
super.viewDidLoad()
picker.delegate = self
picker.dataSource = self
picker2.delegate = self
picker2.dataSource = self
txt_make.inputView = picker
txt_model.inputView = picker2
txt_make.clearButtonMode = .Always
txt_model.clearButtonMode = .Always
parseJSON2()
}
func parseJSON2() {
let path : String = NSBundle.mainBundle().pathForResource("json2", ofType: "json")! as String
let jsonDATA = NSData(contentsOfFile: path) as NSData!
numberOfRowsMake = readableJSON["Cars"].count
for var i = 0; i < numberOfRowsMake; ++i {
let make = readableJSON["Cars"][i]["Manufacturer"].stringValue
makeArray.append(make)
}
}
func parseJSON3() {
let path : String = NSBundle.mainBundle().pathForResource("json2", ofType: "json")! as String
let jsonDATA = NSData(contentsOfFile: path) as NSData!
numberOfRowsMake = readableJSON["Cars"].count
for var i = 0; i < numberOfRowsMake; ++i {
let make = readableJSON["Cars"][i]["Manufacturer"].stringValue
let model = readableJSON["Cars"][i]["Model"].stringValue
print(txt_make.text)
if make == txt_make.text {
modelArray.append(model)
}
}
dump(modelArray)
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == picker {
return numberOfRowsMake
}
if pickerView == picker2 {
return numberOfRowsModel
}
return 1
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == picker {
txt_make.text = makeArray[row]
}
if pickerView == picker2 {
self.picker2.reloadAllComponents()
parseJSON3()
txt_model.text = modelArray[row]
}
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == picker {
return makeArray[row]
}
if pickerView == picker2 {
return modelArray[row]
}
return ""
}
}
Here is the local JSON file.
{
"Cars" :
[{
"Manufacturer": "ABARTH1",
"Model": "500, 2012 onwards",
}, {
"Manufacturer": "ABARTH1",
"Model": "500, 2012 onwards",
}, {
"Manufacturer": "ABARTH1",
"Model": "500, 2012 onwards",
}, {
"Manufacturer": "ABARTH2",
"Model": "500, 2012 onwards",
}, {
"Manufacturer": "ABARTH2",
"Model": "500, 2012 onwards",
}, {
"Manufacturer": "ABARTH2",
"Model": "500, 2012 onwards",
}
]
}

Related

Display List of data when button is clicked

I have 2 different JSON and I want to display list of data when the image from the collectionview is pressed to my another view controller.
Those list of data should be clickable also.
It would be one SkillsName(TSCSkillName) to many Training's (TSCTtopicName)
SAMPLE JSON
{
"TSCskillID": 1,
"TSCProficiency": "Product",
"TSCLevel": "Fundamental",
"TSCSkillName": "Product Usability",
"TSCskillLOGO": "images\/TSCskillLogo\/Product Usability.jpg",
"TSCskillDescription": "SKILLS Test Description"
}
For the second JSON
{
"TSCProficiency": "Product",
"TSCSkillName": "Product Usability",
"TSCskillDescription": "SKILLS Test Description",
"TSCLevel": "Fundamental",
"TSCskillLOGO": "images\/TSCskillLogo\/Product Usability.jpg",
"TSCTtopicID": 1,
"TSCTtopicName": "Trend Micro Security",
"TSCTtopicDescription": "TOPIC Test Description",
"Status": "Done",
"TSCTMemorabilia": "images\/Memorabilia"
},
{
"TSCProficiency": "Product",
"TSCSkillName": "Product Usability",
"TSCskillDescription": "SKILLS Test Description",
"TSCLevel": "Fundamental",
"TSCskillLOGO": "images\/TSCskillLogo\/Product Usability.jpg",
"TSCTtopicID": 2,
"TSCTtopicName": "Trend Micro Antivirus for Mac",
"TSCTtopicDescription": "TOPIC Test Description",
"Status": "Done",
"TSCTMemorabilia": "images\/Memorabilia"
}
// I used this data to display the images to my collectionview
struct getSkills: Codable {
let TSCProficiency, TSCSkillName, TSCskillDescription, TSCLevel: String
let TSCskillLOGO: String
let TSCTtopicID: Int?
let TSCTtopicName, TSCTtopicDescription, status, TSCTMemorabilia: String
enum CodingKeys: String, CodingKey {
case TSCProficiency = "TSCProficiency"
case TSCSkillName = "TSCSkillName"
case TSCskillDescription = "TSCskillDescription"
case TSCLevel = "TSCLevel"
case TSCskillLOGO = "TSCskillLOGO"
case TSCTtopicID = "TSCTtopicID"
case TSCTtopicName = "TSCTtopicName"
case TSCTtopicDescription = "TSCTtopicDescription"
case status = "Status"
case TSCTMemorabilia = "TSCTMemorabilia"
}
}
struct skills {
static var TSCskillLOGO : String = "Photo Location"
static var TSCskillID: String = "1"
static var TSCProficiency: String = "Skill Proficiency"
static var TSCSkillName: String = "Skill Name"
static var TSCskillDescription: String = "Skill Description"
static var TSCLevel: String = "Skill Level"
static var TSCTtopicID: String = "Trainings ID"
static var TSCTtopicName: String = "Training Name"
static var TSCTtopicDescription: String = "Training Description"
static var Status: String = "Status"
static var TSCTMemorabilia: String = "Memorabilia"
}
struct testSkills: Codable {
let TSCskillID: Int
let TSCProficiency, TSCLevel,TSCSkillName, TSCskillLOGO: String
let TSCskillDescription: String
enum CodingKeys: String, CodingKey {
case TSCskillID = "TSCskillID"
case TSCProficiency = "TSCProficiency"
case TSCLevel = "TSCLevel"
case TSCSkillName = "TSCSkillName"
case TSCskillLOGO = "TSCskillLOGO"
case TSCskillDescription = "TSCskillDescription"
}
}
class SkillsTreeViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet weak var skillsCollectionView: UICollectionView!
#IBOutlet weak var skillsCatLbl: UILabel!
var getSkillsInfo = [getSkills]()
var testSkillsInfo = [testSkills]()
var badges: [UIImage] = []
var isBadgeLoaded = false
var retryTimes = 0
// You may check my code below
override func viewDidLoad() {
super.viewDidLoad()
skillsCollectionView.layer.cornerRadius = 10
skillsCollectionView.layer.masksToBounds = true
skillsCatLbl.text = "Network"
loadData()
}
func loadData() {
handleCollectionViewLayout(collectionView: skillsCollectionView)
getTestSkillsList {
self.addValuesToVariables {
self.handleLoading(view: self.skillsCollectionView, isDoneLoading: !self.isBadgeLoaded)
self.loadImages()
}
}
// getSkillsDetails {}
}
func addValuesToVariables(completed: #escaping () -> ()) {
skills.TSCskillLOGO = testSkillsInfo[0].TSCskillLOGO
skills.TSCProficiency = testSkillsInfo[0].TSCProficiency
skills.TSCSkillName = testSkillsInfo[0].TSCSkillName
skills.TSCskillDescription = testSkillsInfo[0].TSCskillDescription
skills.TSCLevel = testSkillsInfo[0].TSCLevel
skills.TSCskillID = String(testSkillsInfo[0].TSCskillID)
completed()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// return getSkillsInfo.count
return testSkillsInfo.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let collectionviewcell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionviewcell", for: indexPath) as! FAMECell
collectionviewcell.skillsBadgePic?.addImageShadow(shadowOffset: CGSize(width: 0, height: 0), shadowColor: UIColor.black.cgColor, shadowRadius: 0.5, shadowOpacity: 5.0)
collectionviewcell.skillsBadgePic?.contentMode = .scaleAspectFit
if isBadgeLoaded {
activityIndicator.stopAnimating()
collectionviewcell.skillsBadgePic?.image = badges[indexPath.item]
}
return collectionviewcell
//collectionviewcell.skillsBadgePic?.image = getSkillsInfo[indexPath.item].image
//}
// print(getSkillsInfo[indexPath.item].image!)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("User Tapped: \(indexPath.item)")
let selectedCell = skillsCollectionView.cellForItem(at: indexPath) as! FAMECell
let mainStoryboard:UIStoryboard = UIStoryboard (name: "Main", bundle:nil)
let desVC = mainStoryboard.instantiateViewController(withIdentifier: "SkillsTreePopUpViewController") as! SkillsTreePopUpViewController
desVC.badgeTitle = testSkillsInfo[indexPath.item].TSCSkillName
desVC.badgeImage = selectedCell.skillsBadgePic?.image
desVC.badgeDescription = testSkillsInfo[indexPath.item].TSCskillDescription
desVC.skillID = testSkillsInfo[indexPath.item].TSCskillID
desVC.trainingsBtn = getSkillsInfo[indexPath.item].TSCTtopicName //getting an error on this line [array is nil]
self.present(desVC, animated: true, completion: nil)
}
func getTestSkillsList(completed: #escaping () -> ()) {
let fcat = self.skillsCatLbl.text
let siebelid = engineerProfileInfo.siebelID
let rootLink = "https://skills.dasq.com/iOS/testskills.php?"
let url = URL (string: rootLink + "id=" + siebelid + "&fcat=" + fcat!)
URLSession.shared.dataTask(with: url!) {(data, response, error) in
if error == nil {
do {
self.testSkillsInfo = try JSONDecoder().decode([testSkills].self, from: data!)
print(self.testSkillsInfo)
DispatchQueue.main.async {
completed()
}
} catch {
print("JSON Error: Skills Tree")
self.handleJSONErrorAlert()
}
} else {
self.handleNoNetAlert()
}
}.resume()
}
func getSkillsDetails(completed: #escaping () -> ()) {
let tid = skills.TSCskillID
let siebelid = engineerProfileInfo.siebelID
let rootLink = "https://skills.dasq.com/iOS/getskillspage.php"
let url = URL (string: rootLink + "sid=" + siebelid + "&tid=" + tid )
URLSession.shared.dataTask(with: url!) {(data, response, error) in
if error == nil { // getting an error here that array is nil
do {
self.getSkillsInfo = try JSONDecoder().decode([getSkills].self, from: data!)
DispatchQueue.main.async {
completed()
}
} catch {
print("JSON Error: Trainings Details")
print (error)
self.handleJSONErrorAlert()
}
} else {
self.handleNoNetAlert()
}
}.resume()
}
func loadImages(){
for index in 1...testSkillsInfo.count {
let badgeTitle = testSkillsInfo[index-1].TSCSkillName
let completeLink = "https://skills.dasq.com/" + "images/TSCskillLogo/\(badgeTitle).jpg"
let imageUrlString = completeLink.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)
let url = URL(string: imageUrlString!)
let data = try? Data(contentsOf: url!)
let coloredPic = UIImage(data: data!)
badges.append(coloredPic!)
}
isBadgeLoaded = !isBadgeLoaded
print(badges.count)
self.skillsCollectionView.reloadData()
}
Please check you decodable struct. I have generated one for you. The error shows that
JSON text did not start with array.
So, try to decode "TopicName" which is an array of "TopicNameElement"
SkillName
struct SkillName: Codable {
let tsCskillID: Int
let tscProficiency, tscLevel, tscSkillName, tsCskillLOGO: String
let tsCskillDescription: String
enum CodingKeys: String, CodingKey {
case tsCskillID = "TSCskillID"
case tscProficiency = "TSCProficiency"
case tscLevel = "TSCLevel"
case tscSkillName = "TSCSkillName"
case tsCskillLOGO = "TSCskillLOGO"
case tsCskillDescription = "TSCskillDescription"
}
}
TopicName
typealias TopicName = [TopicNameElement]
struct TopicNameElement: Codable {
let tscProficiency, tscSkillName, tsCskillDescription, tscLevel: String
let tsCskillLOGO: String
let tscTtopicID: Int
let tscTtopicName, tscTtopicDescription, status, tsctMemorabilia: String
enum CodingKeys: String, CodingKey {
case tscProficiency = "TSCProficiency"
case tscSkillName = "TSCSkillName"
case tsCskillDescription = "TSCskillDescription"
case tscLevel = "TSCLevel"
case tsCskillLOGO = "TSCskillLOGO"
case tscTtopicID = "TSCTtopicID"
case tscTtopicName = "TSCTtopicName"
case tscTtopicDescription = "TSCTtopicDescription"
case status = "Status"
case tsctMemorabilia = "TSCTMemorabilia"
}
}

how to add a column to pre-exisiting pickerview

I need a multiple component pickerview, but I need to add a new column to the far left of it. So far it only has two of the three I need. Here is the current code. I have addeded arrays, wrapped an array inside an array, added variables as a column and also changed the outputs.
import UIKit
class Country {
var cats: String
var country: String
var cities: [String]
init(country:String, cities:[String]) {
self.cats = cat
self.country = country
self.cities = cities
}
}
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var pickerView: UIPickerView!
#IBOutlet weak var countryLbl: UILabel!
var countries = [Country]()
override func viewDidLoad() {
pickerView.delegate = self
pickerView.dataSource = self
cats.apppend(Cat(cat: "furry",
countries.append(Country(country: "India", cities: ["Delhi", "Ahmedabad", "Mumbai", "Pune"]))
countries.append(Country(country: "USA", cities: ["New York", "DC", "Fairfax"]))
countries.append(Country(country: "Austrailia", cities: ["Sydney", "Melbourne"]))
super.viewDidLoad()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 3
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return countries.count
}
else {
let selectedCountry = pickerView.selectedRow(inComponent: 0)
return countries[selectedCountry].cities.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return countries[row].country
}
else {
let selectedCountry = pickerView.selectedRow(inComponent: 0)
return countries[selectedCountry].cities[row]
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerView.reloadComponent(1)
let selectedCountry = pickerView.selectedRow(inComponent: 0)
let selectedCity = pickerView.selectedRow(inComponent: 1)
let country = countries[selectedCountry].country
let city = countries[selectedCountry].cities[selectedCity]
countryLbl.text = "Country: \(country)\nCity: \(city)"
}
}
I added the vars but do I add more brackets and then I don't know how to identify the self like why does country = country but cat can't = cat? Also, the first column I'm going to add (far left in the row) will only have 2 choices and won't effect the other choices.
Since the cats component has nothing to do with the countries, do not add cats to your Countries class (which should be a struct, by the way).
Just have a separate cats array in your view controller. And you need to update all of the picker view methods.
struct Country {
let country: String
let cities: [String]
}
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var pickerView: UIPickerView!
#IBOutlet weak var countryLbl: UILabel!
let cats = ["Cat1", "Cat2"]
var countries = [Country]()
override func viewDidLoad() {
pickerView.delegate = self
pickerView.dataSource = self
countries.append(Country(country: "India", cities: ["Delhi", "Ahmedabad", "Mumbai", "Pune"]))
countries.append(Country(country: "USA", cities: ["New York", "DC", "Fairfax"]))
countries.append(Country(country: "Austrailia", cities: ["Sydney", "Melbourne"]))
super.viewDidLoad()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 3
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return cats.count
} else if component == 1 {
return countries.count
} else {
let selectedCountry = pickerView.selectedRow(inComponent: 1)
return countries[selectedCountry].cities.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return cats[row]
} else if component == 1 {
return countries[row].country
} else {
let selectedCountry = pickerView.selectedRow(inComponent: 1)
return countries[selectedCountry].cities[row]
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if component == 0 {
// do something with the new cat
} else if component == 1 || component == 2 {
if component == 1 {
pickerView.reloadComponent(2)
}
let selectedCountry = pickerView.selectedRow(inComponent: 1)
let selectedCity = pickerView.selectedRow(inComponent: 2)
let country = countries[selectedCountry].country
let city = countries[selectedCountry].cities[selectedCity]
countryLbl.text = "Country: \(country)\nCity: \(city)"
}
}
}

Swift 3 JSON to array of objects is very slow

I am upgrading my app from swift 2 to swift 3 and have a significant performance loss when building an array of custom objects. In swift 2 this took a few seconds while in swift 3 it takes around 30 seconds. I am using alamofire to return swiftyJSON, returning about 3000 rows of data. the alamofire return is quick, its looping through this json to build array of custom objects thats slow. These objects greatly simplify the code written when building table cells and passing data to new views.
Code:
class Customer {
var ID: String!
var sysName: String!
var address: String!
var contactID: String!
required init(_name:String?, _id: String?, _address:String?, _contactID:String?) {
//print(json)
if _id != nil {
self.ID = _id
}else{
self.ID = ""
}
if _name != nil {
self.sysName = _name
}else{
self.sysName = ""
}
if _address != nil {
self.address = _address
}else{
self.address = "No Address on File"
}
if _contactID != nil {
self.contactID = _contactID
}else{
self.contactID = ""
}
}
}
Alamofire.request(API.Router.customerList()).responseJSON() {
response in
print(response.request ?? "") // original URL request
print(response.response ?? "") // URL response
print(response.data ?? "") // server data
print(response.result) // result of response serialization
if let json = response.result.value {
print("JSON: \(json)")
self.customers = JSON(json)
self.parseJSON()
}
}
func parseJSON(){
let jsonCount = self.customers["customers"].count
self.totalCustomers = jsonCount
for i in 0 ..< jsonCount {
self.loadedCustomers = i
print("customer = \(self.customers["customers"][i] ["sysName"].string!)")
//VERY SLOW
//create a customer object
let customer = Customer( _name: self.customers["customers"][i]["sysName"].string!, _id: self.customers["customers"][i]["ID"].string!, _address: self.customers["customers"][i]["mainAddr"].string!, _contactID: self.customers["customers"][i]["contactID"].string!)
//add customer to customer array
self.customersArray.append(customer)
}
self.layoutViews() //build view, call all table methods
}
Thanks
Improved code:
import Foundation
import UIKit
import Alamofire
import SwiftyJSON
enum SearchMode{
case name
case address
}
class CustomerListViewController: ViewControllerWithMenu, UITableViewDelegate, UITableViewDataSource, UISearchControllerDelegate, UISearchBarDelegate, UISearchDisplayDelegate, UISearchResultsUpdating{
var indicator: SDevIndicator!
var totalCustomers:Int!
//data arrays
var ids = [String]()
var names = [String]()
var addresses = [String]()
var searchController:UISearchController!
var currentSearchMode = SearchMode.name
var customerTableView:TableView = TableView()
var layoutVars:LayoutVars = LayoutVars()
var sections : [(index: Int, length :Int, title: String)] = Array()
var customersSearchResults:[String] = []
var shouldShowSearchResults:Bool = false
let viewsConstraint_V:NSArray = []
let viewsConstraint_V2:NSArray = []
override func viewDidLoad() {
super.viewDidLoad()
title = "Customer List"
view.backgroundColor = layoutVars.backgroundColor
getCustomerList()
}
func getCustomerList() {
//remove any added views (needed for table refresh
for view in self.view.subviews{
view.removeFromSuperview()
}
// Show Indicator
indicator = SDevIndicator.generate(self.view)!
Alamofire.request(API.Router.customerList()).responseJSON() {
response in
//print(response.request ?? "") // original URL request
//print(response.response ?? "") // URL response
//print(response.data ?? "") // server data
//print(response.result) // result of response serialization
do {
if let data = response.data,
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any],
let customers = json["customers"] as? [[String: Any]] {
for customer in customers {
if let id = customer["ID"] as? String {
self.ids.append(id)
}
if let name = customer["sysName"] as? String {
self.names.append(name)
}
if let address = customer["mainAddr"] as? String {
self.addresses.append(address)
}
}
}
} catch {
print("Error deserializing JSON: \(error)")
}
// build sections based on first letter(json is already sorted alphabetically)
var index = 0;
var firstCharacterArray:[String] = [" "]
for i in 0 ..< self.names.count {
let stringToTest = self.names[i].uppercased()
let firstCharacter = String(stringToTest[stringToTest.startIndex])
if(i == 0){
firstCharacterArray.append(firstCharacter)
}
if !firstCharacterArray.contains(firstCharacter) {
let title = firstCharacterArray[firstCharacterArray.count - 1]
firstCharacterArray.append(firstCharacter)
let newSection = (index: index, length: i - index, title: title)
self.sections.append(newSection)
index = i;
}
if(i == self.names.count - 1){
let title = firstCharacterArray[firstCharacterArray.count - 1]
let newSection = (index: index, length: i - index, title: title)
self.sections.append(newSection)
}
}
self.layoutViews()
}
}
func layoutViews(){
indicator.dismissIndicator()
searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.placeholder = "Search Customers"
searchController.searchResultsUpdater = self
searchController.delegate = self
searchController.searchBar.delegate = self
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = false
navigationItem.titleView = searchController.searchBar
let items = ["Name","Address"]
let customSC = SegmentedControl(items: items)
customSC.selectedSegmentIndex = 0
customSC.addTarget(self, action: #selector(self.changeSearchOptions(sender:)), for: .valueChanged)
self.view.addSubview(customSC)
self.customerTableView.delegate = self
self.customerTableView.dataSource = self
self.customerTableView.register(CustomerTableViewCell.self, forCellReuseIdentifier: "cell")
self.view.addSubview(self.customerTableView)
//auto layout group
let viewsDictionary = [
"view2":customSC,
"view3":self.customerTableView
]as [String:AnyObject]
let sizeVals = ["fullWidth": layoutVars.fullWidth,"width": layoutVars.fullWidth - 30,"navBottom":layoutVars.navAndStatusBarHeight,"height": self.view.frame.size.height - 100] as [String:Any]
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view2(fullWidth)]", options: [], metrics: sizeVals, views: viewsDictionary))
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view3(fullWidth)]", options: [], metrics: sizeVals, views: viewsDictionary))
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-navBottom-[view2(40)][view3(height)]", options: [], metrics: sizeVals, views: viewsDictionary))
}
/////////////// Search Methods ///////////////////////
func changeSearchOptions(sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case 0:
currentSearchMode = .name
break
case 1:
currentSearchMode = .address
break
default:
currentSearchMode = .name
break
}
filterSearchResults()
}
func updateSearchResults(for searchController: UISearchController) {
filterSearchResults()
}
func filterSearchResults(){
customersSearchResults = []
switch currentSearchMode {
case .name:
self.customersSearchResults = self.names.filter({( aCustomer: String ) -> Bool in
return (aCustomer.lowercased().range(of: self.searchController.searchBar.text!.lowercased()) != nil) })
break
case .address:
self.customersSearchResults = self.addresses.filter({( aCustomer: String) -> Bool in
return (aCustomer.lowercased().range(of: self.searchController.searchBar.text!.lowercased()) != nil)
})
break
}
self.customerTableView.reloadData()
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
//print("searchBarTextDidBeginEditing")
shouldShowSearchResults = true
self.customerTableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
shouldShowSearchResults = false
self.customerTableView.reloadData()
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
if !shouldShowSearchResults {
shouldShowSearchResults = true
self.customerTableView.reloadData()
}
searchController.searchBar.resignFirstResponder()
}
/////////////// TableView Delegate Methods ///////////////////////
func numberOfSections(in tableView: UITableView) -> Int {
if shouldShowSearchResults{
return 1
}else{
return sections.count
}
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
//print("titleForHeaderInSection")
if shouldShowSearchResults{
return nil
}else{
if(sections[section].title == "#"){
return " # \(self.totalCustomers) Customers Found"
}else{
return " " + sections[section].title //hack way of indenting section text
}
}
}
func sectionIndexTitles(for tableView: UITableView) -> [String]?{
print("sectionIndexTitlesForTableView 1")
if shouldShowSearchResults{
return nil
}else{
//print("sectionIndexTitlesForTableView \(sections.map { $0.title })")
return sections.map { $0.title }
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
//print("heightForHeaderInSection")
if shouldShowSearchResults{
return 0
}else{
return 50
}
}
func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
return index
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//print("numberOfRowsInSection")
if shouldShowSearchResults{
return self.customersSearchResults.count
} else {
return sections[section].length
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = customerTableView.dequeueReusableCell(withIdentifier: "cell") as! CustomerTableViewCell
customerTableView.rowHeight = 50.0
if shouldShowSearchResults{
let searchString = self.searchController.searchBar.text!.lowercased()
if(currentSearchMode == .name){
cell.nameLbl.text = self.customersSearchResults[indexPath.row]
cell.name = self.customersSearchResults[indexPath.row]
if let i = self.names.index(of: cell.nameLbl.text!) {
//print("\(cell.nameLbl.text!) is at index \(i)")
cell.addressLbl.text = self.addresses[i]
cell.address = self.addresses[i]
cell.id = self.ids[i]
} else {
cell.addressLbl.text = ""
cell.address = ""
cell.id = ""
}
//text highlighting
let baseString:NSString = cell.name as NSString
let highlightedText = NSMutableAttributedString(string: cell.name)
var error: NSError?
let regex: NSRegularExpression?
do {
regex = try NSRegularExpression(pattern: searchString, options: .caseInsensitive)
} catch let error1 as NSError {
error = error1
regex = nil
}
if let regexError = error {
print("Oh no! \(regexError)")
} else {
for match in (regex?.matches(in: baseString as String, options: NSRegularExpression.MatchingOptions(), range: NSRange(location: 0, length: baseString.length)))! as [NSTextCheckingResult] {
highlightedText.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellow, range: match.range)
}
}
cell.nameLbl.attributedText = highlightedText
}else{//address search mode
cell.addressLbl.text = self.customersSearchResults[indexPath.row]
cell.address = self.customersSearchResults[indexPath.row]
if let i = self.addresses.index(of: cell.addressLbl.text!) {
cell.nameLbl.text = self.names[i]
cell.name = self.names[i]
cell.id = self.ids[i]
} else {
cell.nameLbl.text = ""
cell.name = ""
cell.id = ""
}
//text highlighting
let baseString:NSString = cell.address as NSString
let highlightedText = NSMutableAttributedString(string: cell.address)
var error: NSError?
let regex: NSRegularExpression?
do {
regex = try NSRegularExpression(pattern: searchString, options: .caseInsensitive)
} catch let error1 as NSError {
error = error1
regex = nil
}
if let regexError = error {
print("Oh no! \(regexError)")
} else {
for match in (regex?.matches(in: baseString as String, options: NSRegularExpression.MatchingOptions(), range: NSRange(location: 0, length: baseString.length)))! as [NSTextCheckingResult] {
highlightedText.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellow, range: match.range)
}
}
cell.addressLbl.attributedText = highlightedText
}
} else {
//print("make cell")
cell.id = self.ids[sections[indexPath.section].index + indexPath.row]
cell.name = self.names[sections[indexPath.section].index + indexPath.row]
cell.address = self.addresses[sections[indexPath.section].index + indexPath.row]
cell.nameLbl.text = self.names[sections[indexPath.section].index + indexPath.row]
cell.addressLbl.text = self.addresses[sections[indexPath.section].index + indexPath.row]
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let indexPath = tableView.indexPathForSelectedRow;
let currentCell = tableView.cellForRow(at: indexPath!) as! CustomerTableViewCell
let customerViewController = CustomerViewController(_customerID: currentCell.id)
navigationController?.pushViewController(customerViewController, animated: false )
tableView.deselectRow(at: indexPath!, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Collection view swift fatal error

Demo Code: DemoViewController:
import UIKit
class DemoViewController: ExpandingViewController {
typealias ItemInfo = (imageName: String, title: String)
private var cellsIsOpen = [Bool]()
private let items: [ItemInfo] = [("item0", "Boston"),("item1", "New York"),("item2", "San Francisco"),("item3", "Washington")]
#IBOutlet weak var pageLabel: UILabel!
}
// MARK: life cicle
extension DemoViewController {
override func viewDidLoad() {
super.viewDidLoad()
registerCell()
fillCellIsOpeenArry()
addGestureToView(collectionView!)
configureNavBar()
}
}
// MARK: Helpers
extension DemoViewController {
private func registerCell() {
let nib = UINib(nibName: String(DemoCollectionViewCell), bundle: nil)
collectionView?.registerNib(nib, forCellWithReuseIdentifier: String(DemoCollectionViewCell))
}
private func fillCellIsOpeenArry() {
for _ in items {
cellsIsOpen.append(false)
private func getViewController() -> ExpandingTableViewController {
let storyboard = UIStoryboard(storyboard: .Main)
let toViewController: DemoTableViewController = storyboard.instantiateViewController()
return toViewController
}
}
private func configureNavBar() {
navigationItem.leftBarButtonItem?.image = navigationItem.leftBarButtonItem?.image!.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
}
}
/// MARK: Gesture
extension DemoViewController {
private func addGestureToView(toView: UIView) {
let gesutereUp = Init(UISwipeGestureRecognizer(target: self, action: #selector(DemoViewController.swipeHandler(_:)))) {
$0.direction = .Up
}
let gesutereDown = Init(UISwipeGestureRecognizer(target: self, action: #selector(DemoViewController.swipeHandler(_:)))) {
$0.direction = .Down
}
toView.addGestureRecognizer(gesutereUp)
toView.addGestureRecognizer(gesutereDown)
}
func swipeHandler(sender: UISwipeGestureRecognizer) {
let indexPath = NSIndexPath(forRow: currentIndex, inSection: 0)
guard let cell = collectionView?.cellForItemAtIndexPath(indexPath) as? DemoCollectionViewCell else { return }
// double swipe Up transition
if cell.isOpened == true && sender.direction == .Up {
pushToViewController(getViewController())
if let rightButton = navigationItem.rightBarButtonItem as? AnimatingBarButton {
rightButton.animationSelected(true)
}
}
let open = sender.direction == .Up ? true : false
cell.cellIsOpen(open)
cellsIsOpen[indexPath.row] = cell.isOpened
}
}
// MARK: UIScrollViewDelegate
extension DemoViewController {
func scrollViewDidScroll(scrollView: UIScrollView) {
pageLabel.text = "\(currentIndex+1)/\(items.count)"
}
}
// MARK: UICollectionViewDataSource
extension DemoViewController {
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
guard let cell = cell as? DemoCollectionViewCell else { return }
let index = indexPath.row % 4
let info = items[index]
cell.backgroundImageView?.image = UIImage(named: info.imageName)
cell.customTitle.text = info.title
cell.cellIsOpen(cellsIsOpen[indexPath.row], animated: false)
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
guard let cell = collectionView.cellForItemAtIndexPath(indexPath) as? DemoCollectionViewCell
where currentIndex == indexPath.row else { return }
if cell.isOpened == false {
cell.cellIsOpen(true)
} else {
pushToViewController(getViewController())
if let rightButton = navigationItem.rightBarButtonItem as? AnimatingBarButton {
rightButton.animationSelected(true)
}
}
}
}
// MARK: UICollectionViewDataSource
extension DemoViewController {
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return collectionView.dequeueReusableCellWithReuseIdentifier(String(DemoCollectionViewCell), forIndexPath: indexPath)
}
}
My code: CollectionViewController:
import UIKit
import Alamofire
import SwiftyJSON
import ExpandingCollection
public
class CellViewController: ExpandingViewController, NSURLConnectionDelegate
{
private var cellsIsOpen = [Bool]()
typealias ItemInfo = UIImage
private var items: [ItemInfo] = []
override public func viewDidLoad() {
itemSize = CGSize(width: 256, height: 335)
super.viewDidLoad()
//let cell: CollectViewCell!
// print(items.count)
refcell()
fillCell()
addGestureToView(collectionView!)
configureNavBar()
// Do any additional setup after loading the view.
}
override public func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func Go(sender: UIButton) {
loadimages("http://www.getmyadvisor.com/solr/getmyadvisor/select?q=mode:(%22Lawyer%22,%20%22CA%22)%20AND%20active:true%20AND%20city:(%22Bangalore%22)%20AND%20locality:(%22Rajaji Nagar%22)%20AND%20caseTypes:(%22Family Dispute%22)&wt=json", completionHandler: {
data in
if data.error == nil{
self.items += data.images!
self.collectionView?.reloadData()
}
})
}
public func loadimages(url: String, completionHandler: (error: NSError?, allImagesString: [JSON]?, images: [UIImage]? ) -> ()) -> (){
let unsafe = url
var data1 = [ItemInfo]()
let bingo = NSURL(string: unsafe.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.whitespaceCharacterSet().invertedSet)!)
Alamofire.request(.GET, bingo!)
.validate()
.responseJSON{ response in
switch response.result{
case .Success:
let json33 = JSON(data: response.data!)
//print(json33)
let allImageStrings = json33["response"]["docs"].flatMap { $0.1["imageData"].first?.1}
for Bro in allImageStrings{
let url = NSURL(string: Bro.string!)
let data = NSData(contentsOfURL: url!)!
let image = UIImage(data: data)
data1.append(image!)
}
completionHandler(error: nil, allImagesString: allImageStrings , images: data1)
self.items = data1
//self.collectionView?.reloadData()
case .Failure(let error):
print(error)
completionHandler(error: error, allImagesString: nil, images: nil)
}
}
}
func refcell(){
let bin = UINib(nibName: "CollectViewCell", bundle: nil)
self.collectionView?.registerNib(bin, forCellWithReuseIdentifier: String(CollectViewCell))
}
func fillCell(){
for _ in items{
cellsIsOpen.append(false)
// self.collectionView!.reloadData()
print(cellsIsOpen.count)
}
}
func getViewController() -> ExpandingTableViewController{
let storyboard = UIStoryboard(storyboard: .Main)
let toViewController: TableViewController1 = storyboard.instantiateViewController()
return toViewController
}
func configureNavBar() {
navigationItem.leftBarButtonItem?.image = navigationItem.leftBarButtonItem?.image!.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
}
//MARK: Gesture
func addGestureToView(toView: UIView) {
let gesutereUp = Init(UISwipeGestureRecognizer(target: self, action: #selector(CellViewController.swipeHandler(_:)))) {
$0.direction = .Up
}
let gesutereDown = Init(UISwipeGestureRecognizer(target: self, action: #selector(CellViewController.swipeHandler(_:)))) {
$0.direction = .Down
}
toView.addGestureRecognizer(gesutereUp)
toView.addGestureRecognizer(gesutereDown)
}
func swipeHandler(sender: UISwipeGestureRecognizer) {
let indexPath = NSIndexPath(forRow: currentIndex, inSection: 0)
guard let cell = collectionView?.cellForItemAtIndexPath(indexPath) as? CollectViewCell else { return }
// double swipe Up transition
if cell.isOpened == true && sender.direction == .Up {
pushToViewController(getViewController())
if let rightButton = navigationItem.rightBarButtonItem as? AnimatingBarButton {
rightButton.animationSelected(true)
}
}
else{
let open = sender.direction == .Up ? true : false
cell.cellIsOpen(open)
cellsIsOpen[indexPath.row] = cell.isOpened
//cellsIsOpen.append(cell.isOpened)
}
}
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
guard let cell = cell as? CollectViewCell else { return }
let index = indexPath.row % 4
//let info = items
cell.backgroundImageView.image = items[index]
//cell.customTitle.text = info.title
print(cellsIsOpen.count)
//cellsIsOpen.append(cell.isOpened)
cell.cellIsOpen(cellsIsOpen[indexPath.row], animated: false)
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
guard let cell = collectionView.cellForItemAtIndexPath(indexPath) as? CollectViewCell
where currentIndex == indexPath.row else { return }
if cell.isOpened == false {
cell.cellIsOpen(true)
} else {
pushToViewController(getViewController())
if let rightButton = navigationItem.rightBarButtonItem as? AnimatingBarButton {
rightButton.animationSelected(true)
}
}
}
override public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.items.count
}
override public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
//let cell = collectionView.cellForItemAtIndexPath(indexPath) as? CollectViewCell
return collectionView.dequeueReusableCellWithReuseIdentifier(String(CollectViewCell), forIndexPath: indexPath)
}
}
My JSON(If required to check I've parsed properly or not):
{
"response" : {
"start" : 0,
"docs" : [
{
"enrollmentId" : [
"2534534246"
],
"fieldName2" : [
"Languages"
],
"locality" : [
"XYZ"
],
"active" : [
true
],
"sex" : [
"Male"
],
"latitude" : [
1.2340
],
"city" : [
"udya"
],
"imageData" : [
"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABkCAYAAAAlg3YKAAA1wklEQVR4AcWd95Nc13XnT+c405MHMyACARDMoCxSibYsrWtXP7h2\/1XXbklea4vyWlW2apUp0SbBIJIgEQaYgMk9nXs\/n\/umgUEgCUis8gN7uvv1fffd+70nn3Mfc3fu3BnHf9IxuXHua76\/\/X5dfRbfeeedr3l4X93dZAJjZpFzKvw3OZcf8fn4e+ppPE6THeeO3\/kxAUsbP+QiH\/l0YsxX\/nF+lBtxnn9++QuP4l94\/VdePnaCOQbLa3LkR+PI8523bFJpokyWJuMAISHhx3Qd1xf4YTwaMXFBEqB8DDkfuTxtvSIhNOn+HjDe2+Pkve81esIPXxtATj+N5z4OaTJOoNfrpVen04n9vf3YvXs3Dvb24sbNm7GxtcUE8lEoFWg5juFwwGsYxWIxSoVClHOFmKrVol7le6kS5y9diHPPXohKvZHwGQp0uie0dIxTAvEYnJM4TBbr5Lkv+2z7Pxugyep4g7wrzpGjQwfnivUHg1i\/cydu81pfX48bN67HzRs3Y8Dkh\/y2v7MXnV4nWRqE79z3\/wOcrF6q09MBWgAAAABJRU5ErkJggg=="
],
"fieldValue2" : [
"English, Hindi, Kannada"
],
"fieldValue1" : [
"11 years"
],
"state" : [
"Karnataka"
],
"id" : "Iuusofijpw",
"email" : [
"cont#dontcare.com"
],
"longitude" : [
12.4352
],
"firstName" : [
"Praqwer"
],
"_version_" : 1521637513434759168,
"experience" : [
10
],
"caseTypes" : [
"A Particular caseType let's say Bheema",
],
"lastName" : [
"Bsdtty"
],
"mode" : [
"Lawyer"
],
"fieldName1" : [
"Experience"
]
},
{
"state" : [
"Karnataka"
],
"languages" : [
"English",
"Hindi",
"Kannada"
],
"lastName" : [
"KWE"
],
"firstName" : [
"RANDARTY"
],
"sex" : [
"Male"
],
"caseTypes" : [
"Bheema",
],
"enrollmentId" : [
"4253646"
],
"mobile" : [
42534346
],
"id" : "Iurweoin",
"imageData" : [
"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAABkCAYAAADzJqxvAAAgAElEQVR4XjS9ebBv2VkdtvY+8zm\/8c5vfj2r1VJrQgNEiMkYi0m2kmAbE3DhlAPEqcSuciquVIrgMhCTgF1BQgSMkW0EthkEGCQQIAQCScgSaqk19Ot+3W++872\/8Yz7nL1T6zvP\/Qelbu793XP28H3rW2t9308d3P2iaxEggIdivcBgmCDQPirTwA8UqlIhiDV8pdB0JZz2AevBg4+mrgHTAoHGMElR1DX8MIJvLKzXojMafgg0dQMFwPM9dI2D8g06aHidD4sWjXYAFBLto1WAcw3asoNrLaxSsF0vLKiqrrJc3fu6t12JWqm5qdnbeWJUJF8OipsQ8UJGq6cvVNjU9MWIbHQUeNhbJxGDSYVn0TPQUv4GxJKG0Skpv+tuHWBqbXQ6WSyOjA\/VtRCUqZYrH4UUv2\/ziJ\/f\/aiwX2jbsXKz3ga\/aN+4CG28vb9o27Fys94Gv2jfuAhtvL2\/aNuxcrPeBr\/g2M2m9YyIB6mAAAAABJRU5ErkJggg=="
],
"active" : [
true
],
"mode" : [
"Kelsa"
],
"city" : [
"Udya"
],
"_version_" : 15216,
"email" : [
"Him#somenone.com"
],
"experience" : [
18223
],
"locality" : [
"XYZ"
]
}
],
"numFound" : 2
},
"responseHeader" : {
"status" : 0,
"QTime" : 5,
"params" : {
"q" : "mode:(\"Lawyer\", \"CA\") AND active:true AND city:(\"Bereello\") AND locality:(\"XYZ\") AND caseTypes:(\"Momerty\")",
"wt" : "json"
}
}
}
In Mycode I'm getting an error on the line cell.cellIsOpen(cellsIsOpen[indexPath.row], animated: false) . But in the DemoCode, it works fine. What I'm I doing wrong? Help please.

getting PickerData data from a Rest WebService

i get data from a web service and my pickerData Array don't save values when i want to use it outside of the Json Parsing bloc.
here's my code
var pickerData: [String] = [String]()
var mag : String!
override func viewDidLoad() {
super.viewDidLoad()
NomMAG.alpha = 0
// \(detectionString)
let str = "http://vps43623.ovh.net/yamoinscher/api/getAllMag"
let url = NSURL(string: str)!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in
if let urlContent = data {
do {
let jsonObject = try NSJSONSerialization.JSONObjectWithData(urlContent, options: [])
if let jsonResult = jsonObject as? [String:AnyObject] {
if let Pick = jsonResult["magasin"] as? [[String:String]] {
for categorie in Pick {
self.mag = categorie["libelle"]!
self.pickerData.append(magasin)
//self.pickerData = [(self.produits[0].magasin)]
}
print(self.pickerData)
dispatch_async(dispatch_get_main_queue()) {
self.picker1.reloadInputViews()
// print(self.produits.count)
}
}
}
} catch {
print("JSON serialization failed", error)
}
} else if let connectionError = error {
print("connection error", connectionError)
}
}
task.resume()
//print(produits.count)
//pickerData = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "autre"]
//print(self.pickerData)
self.picker1.delegate = self
self.picker1.dataSource = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// The number of columns of data
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
// The number of rows of data
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.pickerData.count
}
// The data to return for the row and component (column) that's being passed in
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.pickerData[row]
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerData[row] == "autre"
{
//print(row)
NomMAG.alpha = 1
}
else
{
//print(row.description)
NomMAG.alpha = 0
}
}
I want to get my PickerView full with the data i gained from the JsonParsing and the PickerData Array is null outside the block of code of the Json
Connect delegate and dataSource of the picker view in Interface Builder and replace viewDidLoad with
var pickerData = [String]()
override func viewDidLoad() {
super.viewDidLoad()
let str = "http://vps43623.ovh.net/yamoinscher/api/getAllMag"
let url = NSURL(string: str)!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in
if let urlContent = data {
do {
let jsonObject = try NSJSONSerialization.JSONObjectWithData(urlContent, options: [])
if let jsonResult = jsonObject as? [String:AnyObject],
magasin = jsonResult["magasin"] as? [[String:String]] {
// filter valid items, map them to an array and filter empty strings
self.pickerData = magasin.filter { $0["libelle"] != nil }.map { $0["libelle"]! }.filter { !$0.isEmpty}
}
dispatch_async(dispatch_get_main_queue()) {
self.picker1.reloadAllComponents()
}
} catch {
print("JSON serialization failed", error)
}
} else if let connectionError = error {
print("connection error", connectionError)
}
}
task.resume()
}
You have to add the NomMAG line

Resources