I am building a map-based app in iOS (Objective-C) using HERE maps, and am new to this. I was successful in implementing navigation but I am facing a hitch in implementing voice instruction for navigation. This is the code that I have:
- (void) beginNavigationMethod {
self.mapView.zoomLevel = 17.0;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didUpdatePositionForNavigation) name:NMAPositioningManagerDidUpdatePositionNotification object:[NMAPositioningManager sharedPositioningManager]];
NMAVoiceCatalog *voiceCatalog = [NMAVoiceCatalog sharedVoiceCatalog];
voiceCatalog.delegate = self;
[voiceCatalog updateVoiceCatalog];
[self.navigationManager startTurnByTurnNavigationWithRoute:self.route];
[NMANavigationManager sharedNavigationManager].mapTrackingEnabled = YES;
[NMANavigationManager sharedNavigationManager].mapTrackingAutoZoomEnabled = YES;
[NMANavigationManager sharedNavigationManager].mapTrackingOrientation
= NMAMapTrackingOrientationDynamic;
[NMANavigationManager sharedNavigationManager].speedWarningEnabled = YES;
NSError* error = [[NMANavigationManager sharedNavigationManager] startTurnByTurnNavigationWithRoute:self.route];
NSLog(#"%#",error);
}
- (void)voiceCatalog:(nonnull NMAVoiceCatalog *)voiceCatalog didUpdateWithError:(nullable NSError *)error {
NSLog(#"didUpdateWithError: %#",error);
}
I basically don't know how to proceed with this. My apologies for being so naive. If anyone could guide me through this, it would be a great help.
You can look at docs: https://developer.here.com/documentation/ios-premium/topics/map-voice-instructions.html
Otherwise, where is an example for Android: https://github.com/heremaps/here-android-sdk-examples/issues/36#issuecomment-304873154, if you can go through it it will give you an impression of how to do that.
Please try this code
[[NMANavigationManager sharedNavigationManager] setVoicePackageMeasurementSystem:NMAMeasurementSystemImperialUS];
[[NMAAudioManager sharedAudioManager] setDelegate:self];
[[NMAAudioManager sharedAudioManager]setManagesAudioSession:NO];
Here Map Delegate Method
- (BOOL)audioManager:(NMAAudioManager *)audioManager shouldPlayOutput:(NMAAudioOutput *)output{
return true;
}
Project Setting->General->Capabilities->Background Modes
Related
I'm creating a VR app using the DJI SDK.
I have two UIViews, fpvPreviewView1 and fpvPreviewView2.
How do I create two instances of the same camera? It currently only displays in a single view.
Here's the relevant code.
DJICamera *camera = [self fetchCamera];
if (camera && camera.delegate == self)
[camera setDelegate:nil];
[self resetVideoPreview];
- (DJICamera*) fetchCamera {
if (![DJISDKManager product]) {
return nil;
}
if ([[DJISDKManager product] isKindOfClass:[DJIAircraft class]]) {
return ((DJIAircraft*)[DJISDKManager product]).camera;
}else if ([[DJISDKManager product] isKindOfClass:[DJIHandheld class]]){
return ((DJIHandheld *)[DJISDKManager product]).camera;
}
return nil;
}
[[VideoPreviewer instance] setView:self.fpvPreviewView1];
[[VideoPreviewer instance] setView:self.fpvPreviewView2];
[[VideoPreviewer instance] setView:self.fpvPreviewView1];
[[VideoPreviewer instance] setView:self.fpvPreviewView2];
Time sensitive. Please help!
Thanks!
What you are currently doing is reset the view of the video previewer singleton every time.
What you want to do is create multiple instances of VideoPreviewer and keep a reference to manage properly the resources. VideoPreviewer is heavy.
Try this instead:
self.firstVP = [[VideoPreviewer alloc] init];
[self.firstVP setView:self.fpvPreviewView1];
self.secondVP = [[VideoPreviewer alloc] init];
[self.secondVP setView:self.fpvPreviewView2];
Hope this helps.
I am in the process of making an iOS app (Objective-C), I am nearing the end of my production of the application itself and now I am trying to implements Interstitial Ads. I was before seeing the Blue You are connected to iAd banners before on my app but I do not seem to see them now. My test device (iPhone 5S, iOS 9.2.1) is connected to the internet, so that is not the issue and the account I am using is a free developer account, not a paid one.
Below is code from one of my view controllers (the code is identical on all three of them with regard to iAd), I got the code from Apple's test project and modified it slightly.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self cycleInterstitial];
// Other non-relavent stuff
}
- (void)like: (UIButton*)button {
// Other non-relavent stuff
NSInteger i = arc4random_uniform(3);
if (i == 2) {
[self presentInterlude];
}
}
- (void)cycleInterstitial {
// Clean up the old interstitial...
NSLog(#"Cycling");
self.inter.delegate = nil;
// and create a new interstitial. We set the delegate so that we can be notified of when
self.inter = [[ADInterstitialAd alloc] init];
self.inter.delegate = self;
}
- (void)presentInterlude {
// If the interstitial managed to load, then we'll present it now.
if (self.inter.loaded) {
NSLog(#"Requesting the ad");
[self requestInterstitialAdPresentation];
}
}
- (void)interstitialAdDidUnload:(ADInterstitialAd *)interstitialAd {
[self cycleInterstitial];
}
- (void)interstitialAd:(ADInterstitialAd *)interstitialAd didFailWithError:(NSError *)error {
[self cycleInterstitial];
}
I know it is not my random number as I removed that previously. Any ideas on why my ads are not showing up? Could it be my code, my non-paid developer account, or is it something else?
I am not trying to display an actual ad I am only trying to get that You are connected to iAd popup to display to confirm that my implementation is working, so it should not be the fact that I am using a non-paid developer account.
I just noticed different behaviour in my app after upgrading to iOS9. I have a view that shows the device contacts of the phone.
My code is the following:
if (... == YES)
{
ABRecordSetValue(aContact, kABPersonEmailProperty, email, &anError);
if (anError == NULL)
{
ABUnknownPersonViewController *picker = [[ABUnknownPersonViewController alloc] init];
picker.unknownPersonViewDelegate = self;
picker.displayedPerson = aContact;
picker.allowsAddingToAddressBook = YES;
picker.allowsActions = YES;
picker.alternateName = #"John Appleseed";
picker.title = #"John Appleseed";
picker.message = #"Company, Inc";
[self.navigationController pushViewController:picker animated:YES];
}
Then I use the delegate to make a few decisions
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
//make decisions
return YES or NO;
}
The user taps in a phone number.
In IOS8 >> Code reaches shouldContinueAfterSelectingPerson and then the native dialler appears
In IOS9 >> The native dialler appears BEFORE the code reaches shouldContinueAfterSelectingPerson.
Any way to resolve it?
I am facing the same issue. What I have noticed is, if you do certain calculations within the delegate method (it obviously takes some time to do that calculation) and the native dialer gets called.
So, to avoid this problem, I am immediately returning NO from this delegate method and performing my calculations in a different thread. This is of course a workaround, hope the issue is fixed in the next release of iOS.
I am using EAWiFiUnconfiguredAccessoryBrowser to detect EAWiFiUnconfiguredAccessory. The code to start the accessory search it's the following:
- (void)viewDidLoad {
[super viewDidLoad];
if (_accessories == nil) {
_accessories = [[NSMutableArray alloc] init];
}
if (_browser == nil) {
_browser = [[EAWiFiUnconfiguredAccessoryBrowser alloc] initWithDelegate:self queue:nil];
_browser.delegate = self;
}
}
Unfortunately it does find accessories only the first time the View loads. If I go back to the previous view and then reload the view it does not find them.
I tried:
recreating the browser accessory and restarting the search (does not work)
stopping the search and restarting it (does not work)
This is the latest code I got (refer to this together with the code above):
- (void) viewWillAppear:(BOOL)animated{
NSLog(#"view will appear");
if (_accessories != nil) {
[_accessories removeAllObjects];
}
[self.tableView reloadData];
[self initializeBrowswerAndStartSearch];
}
- (void) initializeBrowswerAndStartSearch{
if (_browser != nil) {
[_browser stopSearchingForUnconfiguredAccessories];
}
[_browser startSearchingForUnconfiguredAccessoriesMatchingPredicate:nil];
}
- (void) viewWillDisappear:(BOOL)animated{
[_browser stopSearchingForUnconfiguredAccessories];
}
It seems that the accessory list information is cached somewhere within the APP. If I restart the APP it will find them so I guess there is something that I am missing.
Any help?
so i have the same problem..you should use the unconfiguredAccessories array. Also, try keeping the instance of the browser alive. If you discover the device once, and you re-instantiate the browser, you wont find it again
EAWiFiUnconfiguredAccessoryBrowser has issues,and doesn't provide reliable result in certain use cases. i think you should try this
- (void) viewWillAppear:(BOOL)animated{
NSLog(#"view will appear");
if (_accessories != nil) {
[_accessories removeAllObjects];
}
[self.tableView reloadData];
[self initializeBrowswerAndStartSearch];
}
below method makes browser object nil and reinitialises it, in this case browser object will always return you updated(i.e, proper) values . it worked perfectly for me.
-(void) initializeBrowswerAndStartSearch
{
// Make EAWiFiUnconfiguredAccessoryBrowser object nil and reinitiate ,start searching again
_browser = nil;
_browser = [[EAWiFiUnconfiguredAccessoryBrowser alloc] initWithDelegate:self queue:nil];
[_browser startSearchingForUnconfiguredAccessoriesMatchingPredicate:nil];
}
anytime you feel EAWiFiUnconfiguredAccessoryBrowser isn't providing proper result , try this.
I also have this issue. So I build a singleton called WAC service, then you can keep this singleton alive during the app life cycle. Anywhere you want to load the unconfigured accissories. Just load it from [_browser unconfiguredAccessories].
I'm preparing to launch my first app and want to have multiple leaderboards inside my game. Currently in sandbox mode I can track and log scores into Game Center successfully. Game Center saves my scores (only if it is higher) and seems to be fully functional.
I know through Itunes Connect we have the ability to set up multiple leaderboards and it seems pretty straight forward. I still want to be able to test multiple leaderboards before publishing my game though. Is there a way to do this in sandbox mode? Currently it seems like my scores are only automatically logged into a default leaderboard. Below is the relevant code I'm using to save/access scores. Thanks!
ABGameKitHelper.m
#pragma mark - Leaderboard
-(void) reportScore:(long long)aScore forLeaderboard:(NSString*)leaderboardId
{
GKScore *score = [[GKScore alloc] initWithCategory:leaderboardId];
score.value = aScore;
[score reportScoreWithCompletionHandler:^(NSError *error) {
if (!error)
{
if(![self hasConnectivity])
{
[self cacheScore:score];
}
if (ABGAMEKITHELPER_LOGGING) NSLog(#"ABGameKitHelper: Reported score (%lli) to %# successfully.", score.value, leaderboardId);
}
else
{
[self cacheScore:score];
if (ABGAMEKITHELPER_LOGGING) NSLog(#"ABGameKitHelper: ERROR -> Reporting score (%lli) to %# failed, caching...", score.value, leaderboardId);
}
}];
}
-(void) showLeaderboard:(NSString*)leaderboardId
{
GKLeaderboardViewController *viewController = [GKLeaderboardViewController new];
viewController.leaderboardDelegate = self;
if (leaderboardId)
{
viewController.category = leaderboardId;
CCLOG(#"Going to category already created");
}
[[self topViewController] presentViewController:viewController animated:YES completion:nil];
}
MainScene.m
- (void)gameCenter {
[[ABGameKitHelper sharedHelper] reportScore:1400 forLeaderboard:#"Score"];
[[ABGameKitHelper sharedHelper] showLeaderboard:#"Score"];
}
I'm not sure if I understand your question properly, but I'll try to answer! Game Center does support multiple leaderboards:
-If you want to send a score to specific leaderboard, you just have to call the function [[ABGameKitHelper sharedHelper] reportScore:X forLeaderboard:LEADERBOARD_ID];, where X represents the score you'd like to send, and LEADERBOARD_ID is the ID of the leaderboard you want to send the score to, as specified in iTunes Connect.
-When you have multiple leaderboards, if you don't want to show just one leaderboard, but a list of them all, you should use the GKGameCenterViewController class instead. However, be careful; this ViewController has been added in iOS 6 only, so you must check which version the device is running. I am also using the ABGameKitHelper, so I've made a function to show this kind of view. Here it goes :
ABGameKitHelper.m
- (void) showGameCenter{
if (![[ABGameKitHelper sharedHelper] hasConnectivity]) return;
//Check if device runs on iOS 5
if([[[UIDevice currentDevice]systemVersion]intValue]==5)
{
//If so, we must use the GKLeaderboardViewController
GKLeaderboardViewController *leaderboard = [[GKLeaderboardViewController alloc] init];
if (leaderboard != nil)
{
leaderboard.leaderboardDelegate = self;
[[self topViewController] presentViewController:leaderboard animated:YES completion:nil];
}
}else if ([[[UIDevice currentDevice]systemVersion]intValue]>=6)
{
//if it runs on iOS 6 or higher, we use GKGameCenterViewController
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil)
{
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateDefault;
[[self topViewController] presentViewController:gameCenterController animated:YES completion:nil];
}
}
}
And don't forget to add :
- (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController{
[gameCenterViewController dismissViewControllerAnimated:YES completion:nil];
}
Using this function will allow you to show a nice view containing all your leaderboards and achievements.
Hope this helps!