Ambiguous use of subscript - arrays

This block of code was working and now it's not. I get the error "Ambiguous use of 'subscript'" on the lat and long variables. What's going on? Is this because of a Swift update?
func showPrecincts() {
var urlBoundaries = "http://www.oklahomadata.org/boundary/1.0/boundary/?contains=" + "\(coords!.latitude)" + "," + "\(coords!.longitude)" + "&sets=precincts"
Alamofire.request(.GET, urlBoundaries, parameters: ["foo": "bar"])
.responseJSON { response in
if let data = response.result.value {
let nestedCoordinates = data.valueForKeyPath("objects.simple_shape.coordinates") as! Array<AnyObject>
let bug1 = nestedCoordinates.first as! Array<AnyObject>
let bug2 = bug1.first as! Array<AnyObject>
let coordinates = bug2.first as! Array<AnyObject>
var convertedCoords: [CLLocationCoordinate2D] = []
for individualCoordinates in coordinates {
let lat = (individualCoordinates[1] as! Double)
let long = (individualCoordinates[0] as! Double)
var newCoords = CLLocationCoordinate2DMake(lat, long)
convertedCoords.append(newCoords)
}
print(convertedCoords)
}

coordinates is cast to an array of AnyObject.
The compiler does not know that it's actually an array of Double in another array.
Downcast coordinates to Array<[Double]>
let coordinates = bug2.first as! Array<[Double]>
then you can get the elements without further type casting
let lat = individualCoordinates[1]
let long = individualCoordinates[0]

Related

convert nsmanganedobject to array to find sum of array

My code below is trying to take core data from a NSManagedObject append it to an array. The core data element is saved as a string. My code is not compelling. Ideally the code should be able to append code into the array then the array is filled, find the sum of the numbers added together and print them into the viewDidLoad() func.
var itemName : [NSManagedObject] = []
func performAction() {
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Data")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
var retrievedData = [Double]()
for data in result as! [NSManagedObject] {
if let value = data.value(forKey: "ee") as? Double {
retrievedData.append(value)
}
}
let arraySum = retrievedData.reduce(0, +)
print(arraySum)
} catch {
print("Failed")
}
}
I reviewed your code when you will need to change small thing over there. Replace performAction function as per my updated answer.
func performAction() {
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Data")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
var retrievedData = [Double]()
for data in result as! [NSManagedObject] {
if let value = data.value(forKey: "ee") as? String {
retrievedData.append(Double(value) ?? 0)
}
}
let arraySum = retrievedData.reduce(0, +)
print(arraySum)
} catch {
print("Failed")
}
}

How to access data outside of an if statement in swift

I want to use the variables or array outside of the if statement. In javascript, you can hoist the variables outside of the if statement, but not sure how to do it in swift? I have tried using a struct, but I am not sure which direction to go in. I want to use num in a function and increment through each array. But, need to be able to access variables through the file.
let jsonWithArrayRoot = try? JSONSerialization.jsonObject(with: fileData, options: [])
var zone: Int
var sound: String
var distance: Int
var title: String
var duration: Int
var type: String
var color: Int
var num:Int
num=0
if let array = jsonWithArrayRoot as? [AnyObject] {
let json = array[num]
test = array
zone = json["zone"] as? Int ?? 0
sound = json["sound"] as? String ?? ""
distance = json["distance"] as? Int ?? 0
title = json["title"] as? String ?? ""
duration = json["duration"] as? Int ?? 0
type = json["type"] as? String ?? ""
color = json["color"] as? Int ?? 0
print(zone)
}
//I want to access variables and later on
print(zone)
print(sound)
print(distance)
print(title)
print(type)
print(color)
Use guard.
guard let array = jsonWithArrayRoot as? [AnyObject] else { return }
let json = array[num]
zone = json["zone"] as? Int ?? zone
sound = json["sound"] as? String ?? sound
distance = json["distance"] as? Int ?? distance
title = json["title"] as? String ?? title
duration = json["duration"] as? Int ?? duration
type = json["type"] as? String ?? type
color = json["color"] as? Int ?? color
Use array variable anywhere now.
You should give your variables default values right away, and then change them later based on the JSON data. Your current code puts the default values inside the JSON parsing block, which means that the variables would have no value if the if let array = jsonWithArrayRoot... fails.
Personally, I would also refactor the as? Int ?? lines to something prettier, but that's another issue.
Here's your code with a minimal fix that should work nicely:
let jsonWithArrayRoot = try? JSONSerialization.jsonObject(with: fileData, options: [])
var zone = 0
var sound = ""
var distance = 0
var title = ""
var duration = 0
var type = ""
var color = 0
var num = 0
if let array = jsonWithArrayRoot as? [AnyObject] {
let json = array[num]
zone = json["zone"] as? Int ?? zone
sound = json["sound"] as? String ?? sound
distance = json["distance"] as? Int ?? distance
title = json["title"] as? String ?? title
duration = json["duration"] as? Int ?? duration
type = json["type"] as? String ?? type
color = json["color"] as? Int ?? color
}

Swift Array sort with JSON

Data:
tried get data from JSON
has code with Swift run on Playground
var roadWayStatusArray = [AnyObject]()
let url = URL(string: "http://od.moi.gov.tw/data/api/pbs")
let data = try? Data(contentsOf: url!)
let json = try? JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
if let results = json as? [String : AnyObject] {
if let result = results["result"] as? [[String : AnyObject]] {
for data in result {
let happendate = data["happendate"] as? String
roadWayStatusArray.append(data as AnyObject!)
}
}
}
I has tried using roadWayStatusArray.sort(by: >) but Xcode report me Ambiguous reference member '>'
How to create sort by hapendate or happentime
Your roadWayStatusArray is an array of AnyObject. There is no > operator defined for AnyObject.
The objects in roadWayStatusArray are actually dictionaries that look like this:
{
UID = "10602090007-0";
areaNm = "\U4e2d\U5c71\U9ad8\U901f\U516c\U8def-\U570b\U9053\Uff11\U865f";
comment = "\U5317\U4e0a.\U4e2d\U58e2\U670d\U52d9\U5340 \U51fa\U53e3\U531d\U9053\U4e2d \U53f3\U5074 \U5c0f\U5ba2\U8eca\U505c\U653e\Uff0c\U99d5\U99db\U7591\U4f3c\U7761\U8457\U4e86";
direction = "\U5317\U4e0a";
happendate = "2017-02-09";
happentime = "01:08:00.0000000";
modDttm = "2017-02-09 01:15:43.603";
region = N;
road = "";
roadtype = "\U5176\U4ed6";
srcdetail = "\U71b1\U5fc3\U807d\U773e";
x1 = "121.73558";
y1 = "25.12263";
}
You need to call sort(by:) with a closure that determines the sort order. For example, if you want to sort by happendate and then happentime:
roadWayStatusArray.sort(by: { (lhsAny, rhsAny) -> Bool in
let lhs = lhsAny as? [String: AnyObject]
let rhs = lhsAny as? [String: AnyObject]
let lhsKey = (lhs?["happendate"] as? String ?? "", lhs?["happentime"] as? String ?? "")
let rhsKey = (rhs?["happendate"] as? String ?? "", rhs?["happentime"] as? String ?? "")
return lhsKey < rhsKey
})

how to get array from dictionary in swift 3

I don't understand how to get array from dictionary, i have tried in this code but i want get array only content and type
This is my array
{
wsResponse = {
aarti =(
{
content = "";
identifier = "slok_one";
title = 1;
type = "\U092d\U0915\U094d\U0924\U093e\U092e\U0930";
},
{
content = "";
identifier = "slok_two";
title = 2;
type = "\U092d\U0915\U094d\U0924\U093e\U092e\U0930";
},
{
content = "";
identifier = "slok_three";
title = 3;
type = "\U092d\U0915\U094d\U0924\U093e\U092e\U0930";
}
}
);
};
Here is my code
Alamofire.request(url, method: .get, parameters: nil, encoding: JSONEncoding.default)
.responseJSON { response in
if let status = response.response?.statusCode {
switch(status){
case 201:
print("example success")
default:
print("error with response status: \(status)")
}
}
//to get JSON return value
if let array = response.result.value
{
let JSON = array as! NSDictionary
print("\(JSON)")
let response = JSON["wsResponse"] as! NSDictionary
let data = response["aarti"]
}
}
i want array from this ,like content,title,type
thank you in advance
According to the JSON this prints all values in the aarti array:
if let JSON = response.result.value as? [String:Any] {
if let response = JSON["wsResponse"] as? [String:Any],
let aarti = response["aarti"] as? [[String:Any]] {
for item in aarti {
let content = item["content"] as! String
let identifier = item["identifier"] as! String
let title = item["title"] as! Int
let type = item["type"] as! String
print(content, identifier, title, type)
}
}
}
Basically do not use NSDictionary / NSArray in Swift.
If you want to put all content values in an array use flatMap. The line can replace the whole repeat loop.
let contentArray = aarti.flatMap { $0["content"] as? String }
PS: If you are going to create multiple arrays from the values don't do that: Use a custom struct or class
if someone want to get dictionary of array and use it in tableview
declaration:
var list:[Any] = []
and initialisation :
self.list = (self.ListDic?["data"] as! NSArray!) as! [Any]
and use:
let dictObj = self.list[indexPath.row] as! NSDictionary
print("object value: ",dictObj["text"] as! String)

How can i plot markers on map swift

I'm taking JSON's data and storing all geox coming from JSON in geox and geoy in geoy.
while plotting markers by for loop throws me error "cannot convert value of type NSArray to expected argument type CLLocationDegrees(aka Double)"
let data = JSON as! NSDictionary
let result = Data["result"] as! NSArray
let geox = result.valueForKey("geo_x") as! NSArray
let geoy = result.valueForKey("geo_y") as! NSArray
let count = geox.count
for index in 0...count {
let position = CLLocationCoordinate2DMake(geox,geoy)
let marker = GMSMarker(position: position)
marker.map = mapView
}
Can anyone point me in the direction to solve this?
If I understand, you receive two separate arrays : one for longitude coordinates and another for latitude.
So you can do something like that :
First replace this :
let geox = result.valueForKey("geo_x") as! NSArray
let geoy = result.valueForKey("geo_y") as! NSArray
by this :
let geox = result.valueForKey("geo_x") as! [CLLocationDegrees]
let geoy = result.valueForKey("geo_y") as! [CLLocationDegrees]
and then :
for index in 0...count {
let position = CLLocationCoordinate2DMake(geox[index],geox[index])
let marker = GMSMarker(position: position)
marker.map = mapView
}

Resources