문제

I am trying to make an application that use iBeacons to trigger audio when within a certain proximity. In this case it is when in the immediate proximity of the beacon. I have written an if statement that does this the only problem is that the audio file keeps restarting for as long as the device is in that proximity. I want it to trigger only once, play and finish. Not keep triggering over and over again.

The audio to play is defined here.

-(void)playSound
{
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/05 Rooster.m4a", [[NSBundle mainBundle] resourcePath]]];

NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 1;
audioPlayer.currentTime = 0;
audioPlayer.volume = 100.0;

[audioPlayer play];
}

The audio is later called in the if statement

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
beacon = [beacons lastObject];

self.beaconFoundLabel.text = @"In Range";
self.proximityUUIDLabel.text = beacon.proximityUUID.UUIDString;
self.majorLabel.text = [NSString stringWithFormat:@"%@", beacon.major];
self.minorLabel.text = [NSString stringWithFormat:@"%@", beacon.minor];
self.accuracyLabel.text = [NSString stringWithFormat:@"%f", beacon.accuracy];

if (beacon.proximity == CLProximityUnknown) {
    self.distanceLabel.text = @"Unknown Proximity";
}

else if (beacon.proximity == CLProximityImmediate)
{
    self.distanceLabel.text = @"Immediate";

    self.view.backgroundColor = [UIColor greenColor];
    _portrait.hidden = YES;
    _portraitText.hidden = YES;
    _landscape.hidden = NO;
    _landscapeText.hidden = NO;

    _artworkTitle.text = @"Impression, Sunrise (Impression, soleil levant), 1872";


    UIImage *photo = [UIImage imageNamed: @"Sunrise.png"];
    [_landscape setImage:photo];
    _landscapeText.text = @"Dated 1872, its subject is the harbour of Le Havre in France, using very loose brush strokes that suggest rather than delineate it. Monet explained the title later: \n\nLandscape is nothing but an impression, and an instantaneous one, hence this label that was given us, by the way because of me. I had sent a thing done in Le Havre, from my window, sun in the mist and a few masts of boats sticking up in the foreground.\n\n They asked me for a title for the catalogue, it couldn't really be taken for a view of Le Havre, and I said: 'Put Impression.'";

    [self playSound];


}
도움이 되었습니까?

해결책 2

The other poster's code would let you avoid triggering the sound from playing the same sound multiple times at once. I gather that instead you only want the sound to be played once when you reach a given proximity.

You can adapt Armand's code to do that. Rename the boolean to be "hasPlayed"

Then make your didRange call look something like this:

void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region 
{
//Do whatever else you need to do to handle the ranging call
  if (!self.hasPlayed)
  {
    [self playSound];
    self.hasPlayed = true;
  }
}

Get rid of the custom code in audioPlayerDidFinishPlaying:successfully: that clears the flag.

If you want to keep track of multiple beacons, and want to play your sound when the user enters the proximity of a different beacon, it's a little more complicated.

If you use the same UUID but a different major value, say, then instead of a boolean, save a unique id of some sort (like the major value) for the last beacon who's sound you've played. Let's call the property lastBeaconRanged. Then when you range a beacon, see if the ranged beacon's ID matches the one who's sound you played last. If not, play the sound and save this beacon's ID into your lastBeaconRanged property.

다른 팁

Define a property like Bool isPlaying, and set it to false in viewDidLoad

implement (this is call when finished playing current song) :

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
        self.isPlaying = false;
}

Don't manage iBeacon change while playing, in

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
  if (self.isPlaying) return;

...

  [self playSound];
  self.isPlaying = true;
}

Hop this can help

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top