error in FOR IN loop - arrays

I am trying to run the below function for the array quandlURLs in a for in loop. I am getting an error in line "loadDataFromURL", saying :can not convert value of type [String] to expected argument of type 'Sting'. Can somebody please tell me what I am missing here. Thanks!!
class func getDataFromQuandlWithSuccess(success: ((Quandl: NSData!) -> Void)) {
let quandlGold = "https://www.quandl.com/api/v3/datasets/LBMA/GOLD.json?auth_token=xyzDP7Cj-2F_Jss7sYHf&rows=1"
quandlURLs = [quandlGold, quandlSilver,quandlPlatinum,quandlPalladium]
var index: Int
var urlData = [String]()
for index in quandlURLs {
loadDataFromURL(NSURL(string: quandlURLs[index])!, completion:{(data, error) -> Void in
//2
if let urlData[index] = data {
//3
success(Quandl: urlData[index])
//below worked and showed raw data
//print("Successful \(urlData)")
}
})
}
}
here is the loadDataFromURL function
class func loadDataFromURL(url: NSURL, completion:(data: NSData?, error: NSError?) -> Void) {
let session = NSURLSession.sharedSession()
// Use NSURLSession to get data from an NSURL
let loadDataTask = session.dataTaskWithURL(url, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
if let responseError = error {
completion(data: nil, error: responseError)
} else if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode != 200 {
let statusError = NSError(domain:"com.raywenderlich", code:httpResponse.statusCode, userInfo:[NSLocalizedDescriptionKey : "HTTP status code has unexpected value."])
completion(data: nil, error: statusError)
} else {
completion(data: data, error: nil)
}
}
})
loadDataTask.resume()
}
}

All you need to do here is change for index in quandlURLs to for index in 0..<quandlURLs.count
There was also an issue with if let urlData[index] = data, because you can't use optional binding with an array, you need to define a new value, so go if let urlDataEntry = data, in which case your urlIndex array should be of type NSData.
You also don't need the var index: Int line. Int is inferred when using the for in loop on the ..< function that creates an Int array, and the index variable is usable throughout the for loop.
For example:
class func getDataFromQuandlWithSuccess(success: ((Quandl: NSData!) -> Void)) {
let quandlGold = "https://www.quandl.com/api/v3/datasets/LBMA/GOLD.json?auth_token=xyzDP7Cj-2F_Jss7sYHf&rows=1"
quandlURLs = [quandlGold, quandlSilver,quandlPlatinum,quandlPalladium]
var urlData = [NSData]()
for index in 0..<quandlURLs.count {
loadDataFromURL(NSURL(string: quandlURLs[index])!, completion:{(data, error) -> Void in
//2
if let urlDataEntry = data {
//3
urlData[index] = urlDataEntry
success(Quandl: urlDataEntry)
//below worked and showed raw data
//print("Successful \(urlData)")
}
})
}
}

Related

Could not get JSONArray in variable Swift

So basically I want to make a TableList from my REST service. The REST service can be decoded by this code block:
func getAllParkeergarages(_ completion: #escaping ([Parkeergarage]) -> ()) {
if let url = URL(string: "http://localhost:8080/parkeergarages") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
do {
let res = try JSONDecoder().decode([Parkeergarage].self, from: data)
print(res)
completion(res)
return
} catch let error {
print(error)
}
}
}.resume()
}
}
By using this codeblock I can print the whole JSON in my terminal:
getAllParkeergarages { (array) in
print(array)
}
To get the data in a TableView I need to have the data in a variable. But here is where I get stuck. I tried some different methodes like:
private var data: [Parkeergarage] = getAllParkeergarages { (array) in
return array
}
but is gives me an error: 'Cannot convert value of type '()' to specified type '[Parkeergarage]'. Can someone help me get the result of the function in the variable?
you should do
private var data: [Parkeergarage] = []
in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
getAllParkeergarages { (array) in
self.data = array
self.tableView.reloadData()
}
}
I cannot explain any more.

Escaping closure captures mutating 'self' parameter while decode JSON Swift

I try to parse JSON with mvc pattern.I'm trying for the first time. But I'm getting "Escaping closure captures mutating 'self' parameter error " I mutated functions and put self where necessary.I can access and use required protocols in ViewController. Everything seems normal What's the problem here ?
import Foundation
protocol ItunesManagerDelegate {
func didUpdateSearchin(_ ItunesManager:ItunesManager, product: [ItunesModel])
func didFailWithError(error:Error)
}
struct ItunesManager {
let baseURL = "https://itunes.apple.com/search?term="
var delegate : ItunesManagerDelegate?
var itunesDataArray = [ItunesModel]()
mutating func getSearchResult(for terms:String){
let urlString = "\(baseURL)\(terms)"
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
self.delegate?.didFailWithError(error: error!)
return
}
if let searchResult = self.parseJSON(data!){
self.delegate?.didUpdateSearchin(ItunesManager(), product: searchResult)
}
}
task.resume()
}
}
mutating func parseJSON(_ itunesData:Data) -> [ItunesModel]? {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode([ItunesData].self, from: itunesData)
decodedData.forEach { (ItunesData) in
ItunesData.results.forEach { (SearchResults) in
let type = SearchResults.wrapperType
let name = SearchResults.collectionName
let url = SearchResults.artworkUrl100
let price = SearchResults.collectionPrice
let date = SearchResults.releaseDate
let itunesProductInfo = ItunesModel(collectionName: name, collectionPrice: price, artWorkUrl100: url, wrapperType: type, releaseDate: date)
itunesDataArray.append(itunesProductInfo)
}
}
return itunesDataArray
}catch{
delegate?.didFailWithError(error: error)
return nil
}
}
}

Cannot invoke index with an argument list of type '(of: Any)'

I am making a news app where you can select topics that you want to see. The problem I am having is where you deselect the topic. All of the selected topics are added to CoreData in an Entity called ArticleSource under the Attribute of source. The error occurs when I try to locate the topic in the array called Results using the string title. As I dont know the position of the topic in the array I try to locate it using index(of: ) method which produces the error: Cannot invoke index with an argument list of type '(of: Any)'
Any help appreciated.
do {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "ArticleSource")
request.returnsObjectsAsFaults = false
var results = try context.fetch(request)
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let source = result.value(forKey: "source") as? String {
if source == title {
print("it matches")
if let index = results.index(of: title) {
results.remove(at: index)
}
}
print("results = \(results)")
}
}
}
} catch {
print("error")
}
do {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
try context.save()
print("SAVED")
} catch {
// error
}
There is no need to loop through results to get the index. You can try this.
var results = context.fetch(request)
if let index = results.index(where: { (result) -> Bool in
result.value(forKey: "source") == title
})
{
results.remove(at: index)
}
A likely cause of Cannot invoke index with an argument list of type '(of: X)
is because the type X does not conform to Equatable
In arr.index(of: <Element>), Element should conform to Equatable, and type X does not conform to Equatable:
For an array of [X], use arr.index(where:)
Update your code as:
if let index = results.index(where: { $0 as? String == title }) {
print(index)
}

Cannot pass JSON array to array

I am trying to pass my JSON array to an array called array so that I can then query the array with submission_id with value 27 to obtain the safety_rating_id, schedule_job_id, score and submission_id from this JSON https://codeshare.io/UqJMV but I'm being thrown this error
Cannot convert value of type '[JSON]' to expected argument type 'JSON'
Code to pass JSON to array:
var array: [JSON] = []
func getTask(onCompletion: () -> (), onError: ((NSError) -> ())? = nil) {
guard let endPoint = Data.sharedInstance.weeklyEndpoint
else { print("Empty endpoint"); return }
Alamofire.request(.GET, endPoint, encoding: .JSON)
.validate()
.responseJSON { response in
switch response.result {
case .Success:
if let value = response.result.value {
let json = JSON(value)
for (_,subJson):(String, JSON) in json {
if let date = subJson["start_date"].string{
self.date = date
}
if let building = subJson["building_name"].string{
self.building = building
}
if let jobId = subJson["schedule_job_id"].int {
self.jobIdArray.append(jobId)
}
if let tasks = subJson["tasks"].array{
Tasks.sharedInstance.datas = tasks
for building in tasks {
if let ratings = building["safety_ratings"].array{
print(ratings)
self.array.append(ratings)
}
}
}
}
onCompletion()
}
case .Failure(let error):
print("Request failed with error: \(error)")
onError?(error)
}
}
}
append() expects a single element (JSON), but ratings is an array ([JSON]).
That's what the error message says.
To append an array use appendContentsOf:
self.array.appendContentsOf(ratings)

Error while retrieving Parse data into an array

var titles = [String]()
var descriptions = [String]()
func retrieveData () {
var query = PFQuery(className: "Main")
// get the actual data
query.getFirstObjectInBackgroundWithBlock {
(object: PFObject?, error: NSError?) -> Void in
if error != nil || object == nil {
println("Error retrieving data")
} else {
self.titles.append(object["Labels"] as! String) // ERROR!
self.descriptions.append(object["desc1"] as! String) // ERROR!
}
}
}
I have 2 arrays and I want to retrieve data from Parse and add it to those arrays, but I get this error:
Cannot invoke 'append' with an argument list of type '(String)'
What am I doing wrong ?
Edit: this is what I get when I println(object) :
Optional(<Main: 0x7fc24b84e410, objectId: jy7LrEOMk0, localId: (null)> {
Labels = labels;
desc1 = desc1;
desc2 = desc2;
desc3 = desc3;
desc4 = desc4;
desc5 = desc5;
})
Message from debugger: got unexpected response to k packet: OK
After spending several hours trying & searching, this is the correct answer:
self.titles.append(object?.objectForKey("Labels") as! String)
self.descriptions.append(object?.objectForKey("desc1") as! String)
The answer is so simple, but somehow the Parse.com docs don't have a single sample of it. Anyway I hope that helps anyone else who may get stuck at the same problem.

Resources