Dictionary becomes nil when trying to pass back CLLocation object to iOS app extension
I read in the docs: "The contents of the dictionary must be serializable to a property list file." But a CLLocation is not serializable in this way. Presumably you must wrap it up (again) in an NSData before you stick it into the dictionary to be passed across the barrier.
Apple Watch app: run an MKDirectionsRequest through the parent iOS app in the background?
This code works in an app that I am working on. It also works with the app in the background so I think it's safe to say that MKDirectionsRequest
will work in background mode. Also, this is called from the AppDelegate and is wrapped in a beginBackgroundTaskWithName
tag.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
MKPlacemark *destPlacemark = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(destLat, destLon) addressDictionary:nil];
MKPlacemark *currentPlacemark = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(currLat, currLon) addressDictionary:nil];
NSMutableDictionary __block *routeDict=[NSMutableDictionary dictionary];
MKRoute __block *routeDetails=nil;
MKDirectionsRequest *directionsRequest = [[MKDirectionsRequest alloc] init];
[directionsRequest setSource:[[MKMapItem alloc] initWithPlacemark:currentPlacemark]];
[directionsRequest setDestination:[[MKMapItem alloc] initWithPlacemark:destPlacemark]];
directionsRequest.transportType = MKDirectionsTransportTypeAutomobile;
dispatch_async(dispatch_get_main_queue(), ^(){
MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if (error) {
NSLog(@"Error %@", error.description);
} else {
NSLog(@"ROUTE: %@",response.routes.firstObject);
routeDetails = response.routes.firstObject;
[routeDict setObject:[NSString stringWithFormat:@"%f",routeDetails.distance] forKey:@"routeDistance"];
[routeDict setObject:[NSString stringWithFormat:@"%f",routeDetails.expectedTravelTime] forKey:@"routeTravelTime"];
NSLog(@"Return Dictionary: %@",routeDict);
reply(routeDict);
}
}];
});
});
EDIT from OP: The code above probably works in ObjC, but the exact reason why it works is that it is not using MKMapItem.mapItemForCurrentLocation()
. So the working code for me looks as follows:
func routeFromCurrentLocationToLocation(destination: CLLocation, withTransportType transportType: MKDirectionsTransportType) {
// Calculate directions using MapKit
let currentLocation = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2DMake(lat, lng), addressDictionary: nil))
var request = MKDirectionsRequest()
// ...
}
Mapping to Swift Object issue showing nil using Alamofire ObjectMapper
i think you are missing the right documentation of ObjectMapper lib.
Check this Github ObjectMapper.
These are the types supported by the lib:
Int
Bool
Double
Float
String
RawRepresentable
(Enums)Array<AnyObject>
Dictionary<String, AnyObject>
Object<T: Mappable>
Array<T: Mappable>
Array<Array<T: Mappable>>
Set<T: Mappable>
Dictionary<String, T: Mappable>
Dictionary<String, Array<T:Mappable>>
- Optionals of all the above
- Implicitly Unwrapped Optionals of the above
So, if you are trying to map an Object not in that list, the result is nil
.
In your case is var location: CLLocation?
.
If you need to map CLLocation Object, one way is to map a CustomCLLocation with all properties as follows:
JSON(i don't know your Json, this is an example)
"location":{
"long": 43.666,
"lat": 73.4
}
Swift: create another file "CustomCLLocation" for example like the first one but for mapping CLLocation with your Json
var latitude: Double?
var longitude: Double?
required init?(_ map: Map) {
mapping(map)
}
func mapping(map: Map) {
longitude <- map["long"]
latitude <- map["lat"]
}
and now, you can map an "fake" CLLocation Object:
var location: CustomCLLocation?
Then if you want a really CLLocation. just create an Simply Extension like that(add it in the CustomCLLocation file):
extension CLLocation {
public class func createFromCustomCLLocation(custom: CustomCLLocation) -> CLLocation {
return self.init(custom.latitude,custom.longitude)
}
}
Using the conversion:
var locationCLL = CLLocation.createFromCustomCLLocation(location) // now is a CLLocation
Edited: Alamofire Request
I have the same request on my app with the last version of AlamofireObjectMapper for ios 8.0 +
Alamofire.request(.GET, UrlEndpoints.branchUrl()).responseArray { (response: [BranchObjectMapper]?, error : ErrorType?) in
if(error != nil) {
print(error)
}else{
print("data downloaded")
if let response = response {
branchList(response)
for branch in self.branchList {
print(branch.id)
print(branch.name)
}
}
}
}
How to retrieve user's current city name?
What you have to do is setup a CLLocationManager
that will find your current coordinates. With the current coordinates you need to use MKReverseGeoCoder
to find your location.
- (void)viewDidLoad
{
// this creates the CCLocationManager that will find your current location
CLLocationManager *locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
}
// this delegate is called when the app successfully finds your current location
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// this creates a MKReverseGeocoder to find a placemark using the found coordinates
MKReverseGeocoder *geoCoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
geoCoder.delegate = self;
[geoCoder start];
}
// this delegate method is called if an error occurs in locating your current location
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"locationManager:%@ didFailWithError:%@", manager, error);
}
// this delegate is called when the reverseGeocoder finds a placemark
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
MKPlacemark * myPlacemark = placemark;
// with the placemark you can now retrieve the city name
NSString *city = [myPlacemark.addressDictionary objectForKey:(NSString*) kABPersonAddressCityKey];
}
// this delegate is called when the reversegeocoder fails to find a placemark
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
NSLog(@"reverseGeocoder:%@ didFailWithError:%@", geocoder, error);
}
Swift 5 API call data variable nil but API proved working
The solution Postman generated works for me:
import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif
var semaphore = DispatchSemaphore (value: 0)
var request = URLRequest(url: URL(string: "http://a542cd3116ed.ngrok.io/api/v1/public/location/66.68994/10.249066/50")!,timeoutInterval: Double.infinity)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
semaphore.signal()
return
}
print(String(data: data, encoding: .utf8)!)
semaphore.signal()
}
task.resume()
semaphore.wait()
Related Topics
Do Protocols Have an Effect on The Retain Count
Swift Initialization Rule Confusion
How to Change an Associated Value Within an Enum
Switch Statement Where Value Is Int But Case Can Contain Array
How to Convert an Array to List in Realm
How to Present Ads During Certain Scenes in Sprite-Kit
Swiftui Change on Multilevel Children Published Object Change
How to Calculate The Camera Position from Vuforia Gl Matrix
Swiftui Wrapping Hstack with Images
Public Default Init in Protocol
Dynamic Links Firebase Function Not Being Called at All Xcode 12
What's The Difference Between Nsusernotification and Unusernotification in Macos
Swiftui - How to Change The Button's Image on Click
Rlmexception', Reason: 'Attempting to Modify Object Outside of a Write Transaction
Is There a Difference Between Global Initialization Vs Viewdidload Initialization in Swift
Upload Multiple Images to Ftp Server in iOS