iPhone: Problems after application submission in AppStore - iphone

I've submitted my first iPhone App to the AppStore (on 10.09.10) and I have just found out that it was "Ready For Sale" (18.09.10). After a short moment of deep Happiness, I've found out some problems in my App, that I DO NOT have when I install it on my iPhone using XCode:
1) My APP uses the CLLocationManager to get the GPS coordinates. I've already tested it and it works very well, but after downloading my App from AppStore, I've noticed that my App DOES NOT get any coordinates. Normally, after installing a new App on my iPhone, that needs to get the GPS coordinates, the iOS asks me if I want to allow that App to do so, but in the case with my App, the iOS does not ask me that question. Am I missing something?
P.S.: As I submitted my App to the Review-process I did NOT select the option which says that my App "needs the location services" (UIRequiredDeviceCapabilities in my Info.plist). Do you think this was a mistake?
2) I have some "boolean buttons". When the user clicks on the button, it makes a sound. But in the AppStore version, it does not make ANY sound (even the sounds the picker makes when a picturen is taken can not be heard). Here is my method:
- (void) playMCSound:(BOOL)release {
//Get the filename of the sound file:
NSString *path;
if (release) {
path = [NSString stringWithFormat:#"%#%#",
[[NSBundle mainBundle] resourcePath],
#"/releaseClick.wav"];
} else {
path = [NSString stringWithFormat:#"%#%#",
[[NSBundle mainBundle] resourcePath],
#"/cllick.wav"];
}
//declare a system sound id
SystemSoundID soundID;
//Get a URL for the sound file
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
//Use audio sevices to create the sound
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
//Use audio services to play the sound
AudioServicesPlaySystemSound(soundID);
}
Is something wrong with this method? (as I said: it works normally when I install the App using XCode)
My App is "KA Feedback", by the way. But it is only available in Germany.
I would appreciate any suggestion.

With respect to #1, check in the location services settings next to your app name, if location permission is "on" or "off", it's probably in the off position.
And for #2, while this may sound really silly, I have to ask that first, is the volume turned up when you're in say, the iPod app? I'm not talking about the ringer volume, but the volume of audio apps. Check that first. If it is indeed non-mute, then check in your distribution build, that releaseClick.wav (which is what I presume is supposed to be loaded) exists, and is being copied into the app bundle.

Related

playing a sound doesn't work on iPhone

I've added a sound to my app.
In my .h i've added:
CFURLRef soundFileURL;
SystemSoundID soundFile;
in my viewDidLoad in my .m:
soundFileURL = CFBundleCopyResourceURL(
CFBundleGetMainBundle(),
CFSTR("sound"),
CFSTR("mp3"),
NULL);
AudioServicesCreateSystemSoundID(
soundFileURL,
&soundFile);
and lastly i've added a -playSound method:
-(void)playSound {
NSLog(#"playSound");
AudioServicesPlayAlertSound(soundFile); }
It works fine on the iPhone Simulator, but when I build the app on my iPhone the console says the sound was played but it wasn't.
I read that many others had this problem too but I didn't find any solutions.
What's wrong?
It could be your encoding - the audio codecs on the simulator are much different than those provided by your actual iPhone hardware. Try reencoding.
Also - you don't want to use an mp3 for a sound, you want to use a non-compressed file format (I suggest aiff from experience) because there isn't dedicated decoding hardware to support the sound decoding you're trying to do. (There is for playing music, which mp3 is recommended for)
I would recommend AVAudioPlayer in the AVFoundation framework. It has a simple asynchronous interface for sound playback on iOS.
Check out the Apple programming guide here.
I had a similar issue. It turned out I was referencing "Horn.caf" with
NSURL *hornSound = [[NSBundle mainBundle] URLForResource: #"horn"
withExtension: #"caf"];
Note the difference in case; My OS X Lion install is on a case insensitive file system.
Changing the code to the following fixed the issue.
NSURL *hornSound = [[NSBundle mainBundle] URLForResource: #"Horn"
withExtension: #"caf"];
Hope that helps others.

Playing Sound Effects while in Background Mode

I have a need to play some sporadic sound effects in the background of an iPhone app. From everything I've read and experienced with iOS 4, I can keep my app running in the background as long as I am running GPS by specifying "location" as a background mode. That actually works. But at times I want to play a sound effect...in other words, it's not "continuous" sound which I see reference to.
But the app is running, so why can't I just use AVAudioPlayer to play some sound effects? Would another sound API work?
GAHHH!
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"BEEP" ofType:#"aiff"];
NSURL *fileURL = [[[NSURL alloc] initFileURLWithPath: soundFilePath] autorelease];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
player.volume = 1.0;
[player prepareToPlay];
// play
[player play];
I think it is important to clarify that your application is not running in the background. Rather, your application is 'put to sleep'. The info.plist background process value that you specify tells the OS that it should wake your application and allow it to respond to specific types of events. From the Apple Documentation
Each of the preceding values [audio, location, voip] lets the system know that your application should be woken up at appropriate times to respond to relevant events.
In your case, your application is frozen and is only able to respond to the type of event that you specify (location, or GPS).
You don't make it clear what context this code is in, so at this point it's difficult to tell you why the audio is not playing. Also, you need to make sure that your application is running in the background for the specified purpose. If you are using the location mechanism and not using GPS in your app, you may get rejected when you submit your application.
You may also want to refer to the Checklist for Supporting Multitasking to ensure the structure of your application implements their requirements.
[EDIT]
You have a good example of background playback while monitoring GPS position here :
http://www.informit.com/articles/article.aspx?p=1646438&seqNum=5
And it's using AudioToolbox rather than AVAudioPlayer
I've managed to do it using the AVAudioPlayer.
did you also add the audio value in the info.plist for key UIBackgroundModes ?
The answer is that it won't work with AVAudioPlayer. Use the AudioServicesPlaySystemSound API instead.

Sound on simulator but not device

I'm using the following to play an m4a file:
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: fileName];
SystemSoundID soundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
AudioServicesPlaySystemSound(soundID);
It works fine on the simulator but I hear nothing on the device. Sounds files I'm using all stay in the bundle. Here is what filePath looks like from the device:
file://localhost/var/mobile/Applications/418945F3-3711-4B4D-BC65-0D78993C77FB/African%20Adventure.app/Switch%201.m4a
Is there an issue with the file path or any thing different I need to do for the device?
Just as a sidenote - I was having the exact same problem and spent probably close to an hour on converting files to the correct format, etc.. Yet the problem was the "mute" switch on the iPad. So even though the volume was up, and I could hear other sounds on the iPad, because the mute switch was turned on, it wasn't playing system sounds.
To add to the confusion, this app uses text-to-speech and the volume coming from the dictation was perfectly fine, it was only the sounds coming from AudioServicesPlaySystemSound() that weren't being played.
I had trouble with this too. Finally I realised it was because AudioServices can only play audio with the following constratints.
Sound files that you play using this
function must be:
- No longer than 30 seconds in duration
- In linear PCM or IMA4 (IMA/ADPCM) format
- Packaged in a .caf, .aif, or .wav file
From Apple docs: http://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/SystemSoundServicesReference/Reference/reference.html
You might want to use the AVAudioPlayer instead of AudioServices.
The following code will take an audio file (.m4a) and play the audio file 1 time. Don't forget to release "audioPlayer" when you're done with it.
NSString *urlAddress = [[NSBundle mainBundle] pathForResource:#"filename" ofType:#"m4a"];
NSURL *url = [NSURL fileURLWithPath:urlAddress];
NSError *error;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
if (audioPlayer == nil)
{
NSLog([error description]);
}
else
{
[audioPlayer play];
}
Hope this example helps you with playing audio on the actual device. It might also be a good idea to increase the device audio when the file is playing.
Note: You will need to add the AVFoundation framework to your project if you have not already done so. As well as import the header file.
#import <AVFoundation/AVFoundation.h>
Update:
From Apple's Core Audio Overview Document
Audio Session Services
Audio Session Services lets you manage audio sessions in your application—coordinating the audio behavior in your application with background applications on an iPhone or iPod touch. Audio Session Services consists of a subset of the functions, data types, and constants declared in the AudioServices.h header file in AudioToolbox.framework.
The AVAudioPlayer Class
The AVAudioPlayer class provides a simple Objective-C interface for playing sounds. If your application does not require stereo positioning or precise synchronization, and if you are not playing audio captured from a network stream, Apple recommends that you use this class for playback. This class is declared in the AVAudioPlayer.h header file in AVFoundation.framework.
Start by error-checking your returns. Is filePath nil? Do either of the AudioServices functions return an error? The most likely cause is case-sensitivity. The iPhone filesystem is case sensitive while the Mac is not. But the first step in debugging is to look at the errors the system is providing.
The simulator uses regular QuickTime for playback, so it's easy to have media assets which work in the sim, but fail on the device due to missing / unsupported codecs. The test is if you can play the file at all on the device, eg through Safari or the iPod app.

iPhone: how to make key click sound for custom keypad?

Is there a way to programmatically invoke the keypad "click" sound? My app has a custom keypad (built out of UIButtons) and I'd like to provide some audio feedback when the user taps on the keys. I tried creating my own sounds in Garageband, but wasn't happy with any of my creations. If there isn't a standard way to invoke the key click, can anyone point me to a library of sounds that might have such a gem?
There is a really fast solution to play the default keyboard sound:
Add AudioToolbox.framework
Add the following line wherever you want the sound to play:
AudioServicesPlaySystemSound(0x450);
As of iOS 4.2, adopt the UIInputViewAudioFeedback protocol on a custom subclass of UIView. Make this view your "inputView" and then call "playInputClick" at the appropriate time.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIInputViewAudioFeedback_ProtocolReference/Reference/Reference.html
Just to save some people time. Put this in your custom view:
- (BOOL) enableInputClicksWhenVisible {
return YES;
}
To make the click do this:
[[UIDevice currentDevice] playInputClick];
No need to copy the file into your own app - you should be able to get it directly from the UIKit framework:
CFURLRef soundFileURLRef = CFBundleCopyResourceURL(
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.UIKit")),
CFSTR ("Tock"),CFSTR ("aiff"),NULL);
This is what I made out of it aSquared's comment:
NSString *path = [[NSBundle bundleWithIdentifier:#"com.apple.UIKit"] pathForResource:#"Tock" ofType:#"aiff"];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &soundID);
AudioServicesPlaySystemSound(soundID);
AudioServicesDisposeSystemSoundID(soundID);
The simplest way I've found is to extract Tock.aiff (the keyboard sound) from the iPhone Simulator and package it with your app, then play it using AudioServicesPlaySystemSound() at the appropriate time. On my machine, simply typing Tock.aiff into Spotlight turns up the file, but if you have to go looking for it, it's in the simulator version of UIKit.framework.
Using 0x450 as the SystemSoundID works for me (and at the correct volume - just playing the built-in Tock.aiff was too loud). No idea how portable that is - this is on an iPod Touch 3rd gen.
Still doesn't respect the preference for tick on/off.
Here's what I did:
Locate 'Tock.aiff' in: /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/System/Library/Frameworks/UIKit.framework
Drag it into your Resources folder in xCode, ticking 'Copy items into destination group's folder'
Import AVFoundation.framework into the Frameworks folder in xCode
Import AVFoundation at the top of your class:
#import <AVFoundation/AVAudioPlayer.h>
Use the following function:
- (void)PlayClick {
NSURL* musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"Tock"
ofType:#"aiff"]];
AVAudioPlayer *click = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
[click setVolume:0.15f];
[click play];
}
That's it!
From what I can tell, the click sound isn't available to apps. I haven't seen anything in audio session services that is relevant. AudioServicesPlaySystemSound() looks promising, but there doesn't appear to be any system sound ID for the click sound (a closer look at the headers may turn up something). You could always loop over a call to AudioServicesPlaySystemSound(i) and see if anything plays. The iPhone software restore images probably have the sound, but it's probably not licensed for general use. Jailbreaking an iPhone to get at the tasty click sound doesn't need to be mentioned.
For (creative commons) sounds, check out the Freesound Project.
For the future, perhaps request that Apple expose system sounds other than the alert sound for use with AudioServicesPlaySystemSound().
Maybe a bit late ...
But in MrMage last post, if you do AudioServicesDisposeSystemSoundID(soundID); straight after AudioServicesPlaySystemSound(soundID);
then you won't hear a thing as you're discarding the system sound right after creating it.
You have to let it finish playing first.. Only call AudioServicesDisposeSystemSoundID to cancel the sound before it finishes
You do not have to dispose of the sound object right away.
Keep a pointer to that sound object in a property, and dispose of it only when you are about to play another sound before re-creating it.
And of course finally dispose of the SystemSoundID object in dealloc.

Trying to play sound through iPhone Simulator

I'm trying to play a sound file from an iPhone program.
Here's the code:
NSString *path = [[NSBundle mainBundle] pathForResource:#"play" ofType:#"caf"];
NSFileHandle *bodyf = [NSFileHandle fileHandleForReadingAtPath:path];
NSData *body = [bodyf availableData];
NSLog( #"length of play.caf %d",[body length] );
NSURL *url = [NSURL fileURLWithPath:path isDirectory:NO];
NSLog( [url description] );
NSLog( #"%d", AudioServicesCreateSystemSoundID((CFURLRef)url, &soundID) );
The first NSLog is to check that I have access to the file (I did), the second NSLog is to show the file URL, and the third NSLog returns -1500 "An unspecified error has occurred."
For the second NSLog, I get the following output:
file://localhost/Users/alan/Library/Application 敲慬楴敶瑓楲杮upport/iPhone蒠ꁻތĀ⾅獕牥⽳污湡䰯扩慲祲䄯灰楬慣楴湯匠灵潰瑲椯桐湯⁥楓畭慬潴⽲獕牥䄯灰楬慣楴湯⽳䙂㕅㡂㤱䌭䐳ⴸ䐴䙃㠭㍃ⴷ䍁㈶㠵䙁㤴㈰䰯捯瑡䵥⹥灡⽰汰祡挮晡imulator/User/Applications/BFE5B819-C3D8-4DCF-8C37-AC6258AF4902/LocateMe.app/play.caf
This is either due to my misunderstanding of the "description" method, or this contributes to the problem.
Any idea what is going wrong?
The first parameter to NSLog is a format string; you're passing [URL description] as the format string to the second use of NSLog. That's bad, because if the description of the URL contains any % characters then it will wind up printing random stuff from the stack.
Instead, write
NSLog(#"%#", URL);
You don't need to even use -description here; NSLog will invoke it for you automatically because %# means "an object," not "an NSString," and it's smart enough to do the right thing for you.
In addition, it seems that the iPhone simulator does not like to play (systemSound) sounds over 5 seconds in length. I had the same issue as out apps almost always play a start up systemSound.
One of the apps I was working on the simulator would not play the sound but the device would. Later I found that there is some strange limitation on the simulator and the way it handles sounds. I've filed a bug with Apple. Hopefully this will be address with the release of the iPhone SDK 3.0.
An update on this.
I got my keys to allow me to run my app on the device.
I found that my .caf file successfully played when the app ran on the device.
I then tried various alternatives.
A .wav file that is 60 seconds long failed to work on the simulator and the device.
A .wav file that is 5 seconds long would work on the simulator, but not on the device.
A .aiff file that is 5 seconds long works on the simulator and the device.
It would be good to know definitively what the simulator and the device are checking about the file when it is passed to AudioServicesCreateSystemSoundID
I tried the same with my application that plays sounds just fine. The sounds don’t play in the Simulator and when I try to NSLog the URL, I get the same garbage as You and EXC_BAD_ACCESS on the top of it. When I log the URL on the device, the URL is fine, but I get EXC_BAD_ACCESS nevertheless. When I drop the logging, sounds play and everything works. If somebody could explain this behaviour I’d be grateful. As for Your problem, I’d drop the logging and try the code on the device.
Use "AVAudioPlayer" class for playing .caf files