Thiha Aung Thiha Aung - 1 month ago 14
iOS Question

Converting the following code to Swift 2.2

I am trying to convert this code to Swift 2.2.But I am getting this error.

enter image description here

Here is the objective - C Code

- (NSDictionary *)parseLatLonFile:(NSString *)fileName
{
NSMutableDictionary *ret = [NSMutableDictionary new];
NSString *path = [[NSBundle mainBundle] pathForResource:fileName
ofType:@"txt"];
NSString *content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
NSArray *lines = [content componentsSeparatedByString:@"\n"];
for (NSString *line in lines) {
NSArray *parts = [line componentsSeparatedByString:@","];
NSString *latStr = parts[0];
NSString *lonStr = parts[1];

CLLocationDegrees latitude = [latStr doubleValue];
CLLocationDegrees longitude = [lonStr doubleValue];

// For this example, each location is weighted equally
double weight = 1;

CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude
longitude:longitude];
MKMapPoint point = MKMapPointForCoordinate(location.coordinate);
NSValue *pointValue = [NSValue value:&point
withObjCType:@encode(MKMapPoint)];
ret[pointValue] = @(weight);
}

return ret;
}


Here is my converted code

func parseLatLonFile(fileName: String) -> [NSObject : AnyObject] {
var ret = [NSObject : AnyObject]()
var path = NSBundle.mainBundle().pathForResource(fileName, ofType: "txt")!
var content = try! String(contentsOfFile: path, encoding:NSUTF8StringEncoding)
var lines = content.componentsSeparatedByString("\n")
for line: String in lines {
var parts = line.componentsSeparatedByString(",")
var latStr = parts[0]
var lonStr = parts[1]
var latitude = CDouble(latStr)!
var longitude = CDouble(lonStr)!
// For this example, each location is weighted equally
var weight: Double = 1
var location = CLLocation(latitude: latitude, longitude: longitude)
var point = MKMapPointForCoordinate(location.coordinate)
var pointValue = NSValue.value(point, withObjCType: !)
ret[pointValue!] = weight
}
return ret
}


I am trying to use this library to display heatmap :
https://github.com/dataminr/DTMHeatmap

And I am converting this to Swift because I really want to understand how this work..

Any help with that?And if there are some heatmap example in swift are possible,all helps are welcome.I am trying to get kml data and parse it too.

Answer Source

The original code seems to be converting an MKMapPoint (a struct) instance to an NSValue (a class) instance, in order to use it as a dictionary key.

The reason is that, in Objective-C, dictionary keys/values (and array elements) can only be reference-type objects (class instances), not value type objects (struct instances, int, double, etc...).

For Swift dictionaries (and arrays), there is no such constrain: You can have a dictionary with keys of type MKMapPoint, so there is no need to use NSValue.


EDIT: It turns out MKMapPoint does not conform to the protocol Hashable, so you can not use the type as the keys to your dictionary; my mistake.

You could convert your MKMapPoint instance to a string, and use that instead. For example:

var ret = Dictionary<String, Double>()

// ... 

// Convert MKMapPoint to string for use as key:
let key = String(format:"%.2f,%.2f", point.x, point.y)

ret[key] = 1.0