How to print when location changes realtime with Mapbox - ios

I am using the mapbox default drop in UI provided in their SDK for iOS, and I call
let navigationViewController = NavigationViewController(for: route, locationManager: navigationLocationManager())
navigationViewController.delegate = self
present(navigationViewController, animated: true, completion: nil)
This presents a navigation view controller, but when this is presented, I want to somehow print the current location of the user in realtime as he moves along the route. How do I do this without having to build my own custom navigation UI? Is it possible to do this using only the drop in UI?

You can perform lightweight actions in the -mapView:didUpdateUserLocation: delegate method, including printing the user's new location.

Related

How to stop capture session when it is inside the Collection View Cell in iOS , Swift

I have implemented a QR Reader using (AVFoundation) AVCapture Session in iOS. In my ParentViewController I have implemented a CollectionView. inside the collection view cell I have implemented QR Code Reader and I start the capture session start running inside the cell. it works fine and read the metadata output. I stop the session when metadata output delegates called. But If I leave the ParentView Controller the Capture Session is still running and when I navigate to another ViewController it capture the session from background. Why is this and how can I stop the capture session When navigating to another view controller.
Here is the Hierarchy,
ParentViewController --->(inside)CollectionView --->(inside) CollectionViewCell --->(inside) QR Reader with capture session Strat.
What Happens,
ParentViewController ----> (navigate to another controller) Capture Session Still Activated and reads qr codes from background
What I want,
ParentViewController ---->(navigate to another controller) Shouldn't capture anything.
I Tried In ParentViewController, inside viewWillDisappear
override open func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
let qrreaderCell = QRReaderCell()
qrreaderCell.captureSession.stopRunning()
ColletionView.reloadItems(at: [IndexPath(row: 0, section: 0)])
}
but didn't work and failed. can anyone help with this.
You are creating new instance of QRReaderCell.
let qrreaderCell = QRReaderCell()
qrreaderCell.captureSession.stopRunning()
Instead of creating new instance, just access the current cell which contains the QRReader.
let qrreaderCell = collectionView.cellForItem(at: IndexPath(row: 0, section: 0))
qrreaderCell.captureSession.stopRunning()
And make sure your viewWillDisappear get called. and if not, you can stop the capture session right before you navigate to another viewController.
just stop the capture session right before you push or segue to another viewController.
It seems more likely there is a retain cycle, but tough to tell without seeing your cell configuration code.
To stop existing sessions, you should iterate your collection view and stop the session on any already existing cells. You could do this in viewDidDisappear (your approach created a new cell, which would be released anyways at the end of the method)
If you post the cell class and the controller class code perhaps it may be helpful.

How to present custom alertview and system permissions alertviews sequentially in order.

I have an app that uses Location Services and Notifications(I have no control over the alert views they present to confirm/deny permission). The first time I start the app, it asks for permission to use both features from alert views. I also have 2 custom permissions that I want to present as alert views. My question is how do I order them sequentially and have the next alert view appear after I confirm/deny the current one. My initial idea is to have an isPermissionSet flag for each permission and the next permission to be presented requires all the previous permissions to be set before it's able to be presented. After each permission is set, I call a refresh method which checks for all permissions(since my app runs asynchronously). Are there better design patterns that tackle this problem?
For the two custom permissions you can use UIAlertController and UIAlertAction to present the alerts sequentially. I am presuming that the result of one permission does not affect the other permission request. So you can do this
func askPermissions1() {
//Create UIAlertAction objects for Yes and No buttons and in their action handlers call askPermission2()
//Create UIAlertController with the actions created above and present it
}
func askPermissions2() {
//Create UIAlertAction objects for Yes and No buttons and in their action handlers call askLocation()
//Create UIAlertController with the actions created above and present it
}
func askLocation() {
//request for location here and handle the location manager delegate methods to determine what the user has chosen
//In the delegate methods call askPushNotification()
}
func askPushNotification() {
//request for push notification permission and handle their delegate accordingly
}
Hope this helps.

UIDocumentInteractionController - Show "Quick Look" Option

I am using an instance of UIDocumentInteractionController to offer the user the option to open a given document, if a capable app is installed on their device.
Apple's documentation for the QuickLook Framework mentions that:
To display a Quick Look preview controller you can use any of these
options:
Push it into view using a UINavigationController object.
Present it modally, full screen, using the presentModalViewController:animated:
method of its parent class, UIViewController.
Present a document
interaction controller (as described in Previewing and Opening Files.
The user can then invoke a Quick Look preview controller by choosing
Quick Look from the document interaction controller’s options menu.
(emphasis mine)
I am opting for that third option: Instead of using a QLPreviewController, I am presenting an UIDocumentInteractionController; this is my code:
#IBAction func openDocument(sender: AnyObject) {
let interactionController = UIDocumentInteractionController(URL: documentURL)
interactionController.delegate = self
// First, attempt to show the "Open with... (app)" menu. Will fail and
// do nothing if no app is present that can open the specified document
// type.
let result = interactionController.presentOpenInMenuFromRect(
self.view.frame,
inView: self.view,
animated: true
)
if result == false {
// Fall back to options view:
interactionController.presentOptionsMenuFromRect(
self.view.frame,
inView: self.view,
animated: true)
}
}
The fallback path gets executed (options menu), because I don't have any app that can open docx. However, the mentioned "Quick Look" option is not present:
What am I missing?
NOTE: I am not implementing any of the methods of UIDocumentInteractionControllerDelegate.
Silly me... again.
ANSWER: It turns out that, to have the QuickLook option present, you need to implement this method of the delegate protocol:
func documentInteractionControllerViewControllerForPreview(controller: UIDocumentInteractionController) -> UIViewController {
return self // returning self seems to work
}
(I somehow missed this. On a first read, I thought implementing this method meant that I should return a view controller capable of displaying the content -i.e. a full-fledged docx renderer, in this case. It just asks for a "source" from which to show the preview)
Once I implemented that method, the eye button started to appear in the options menu.
But on clicking it, my app would crash: by the time the quick look launches, the UIDocumentInteractionController was deallocated. I changed it from local variable to property, and now it works.

Mapbox selectAnnotation doesn't work in ViewDidLoad or first time in ViewDidAppear

I have a master-detail application, and my details page is a map. When I click on the element in the Master list, the map with whole bunch of markers shows up, zooms/pans into a specific location, and an annotation pops up describing what this location is.
The implementation is pretty simple, so I thought. In my viewDidAppear, I go through the list of annotations in my mapview and just call [mapView selectAnnotation: myAnnotation animated: FALSE] and it works fine. BUT NOT THE FIRST TIME!
I populate my map in ViewDidLoad, and the first time the ViewDidAppear is called, the mapView.annotations array is still empty. Is there a simple way to make it work even when I first enter the details view? Or do I have to create and populate the map in the AppDelegate?
Try using MGLMapViewDelegate and especially
func mapViewDidFinishLoadingMap(mapView: MGLMapView) {
// your code here
}
Maybe you can define a method at the DetailViewController,then when you trigger the method like tableview's didselect or prepareForSegue,you must get the DetailViewController's instance,finally,you can use this instance to call your user-defined method.

Having issues with nib from ios_google_places_autocomplete

Thank you for viewing this page.
I have downloaded the following from GH: https://github.com/watsonbox/ios_google_places_autocomplete
It uses a nib file to initiate a autocomplete feature within a ViewController (in the Main Storyboard.
Issues
The following issues are hindering my progress;
I am unable to close the nib view using the X (or Stop button). The
nib loads via ViewDidLoad, therefore every time it dismisses itself,
it will be shown again. I have attempted to do the following but it
does not work.
When any cell is selected, I am unable to go back to the ViewController I originally navigated from. (same as point 1,
however should happen once I select any of the cells).
extension LocoSearch: GooglePlacesAutocompleteDelegate {
func placeSelected(place: Place) {
println(place.description)
println(place.id)
var locoResult = PFUser.currentUser()
locoResult["placeDesc"] = place.description
locoResult["placeId"] = place.id
locoResult.pin()
self.performSegueWithIdentifier("locoDone", sender: self)
}
func placeViewClosed() {
dismissViewControllerAnimated(true, completion: {
self.performSegueWithIdentifier("locoDone", sender: self)
})
To stop the autocomplete controller from loading every time the view loads, either remove it from viewDidLoad (and put it in a button click handler, for example), or if that's really where it belongs then perhaps use a variable stored property to store the currently selected Place and only show the autocomplete controller if none exists.
placeSelected is the correct callback for handling selections. Perhaps you should dismiss the autocomplete view before performing the segue as you do in your close handler? Please link a Github project with this issue if you really can't get it working.

Resources