CoreMotion framework - compass-geolocation

I recently was doing a compass, to involve CoreMotion framework, but I checked for a long time did not find information on how to implement this framework the effect of the compass, hoping to get everyone's help.

Apple's Core Motion Framework Reference
Apple's Event Handling Guide for iOS: Core Motion
Apple's CoreMotionTeaPot from WWDC ’10 Sample Code
Get Moving with Core Motion — Jonathan Blocksom
Getting you started with CoreMotion — Ludwig Schubert
A similar question: make a compass application in iPad

My "Helloworld" CoreMotion:
1) Add CoreMotion.framework
2) in .h file:
#import <CoreMotion/CoreMotion.h>
3) in .m file:
CMMotionManager *myMotionManager= [[CMMotionManager alloc] init];
myMotionManager.deviceMotionUpdateInterval = 1/60;
[myMotionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical toQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
double x = myMotionManager.deviceMotion.magneticField.field.x;
double y = myMotionManager.deviceMotion.magneticField.field.y;
double z = myMotionManager.deviceMotion.magneticField.field.z;
NSLog(#"Strength of Earth's magnetic field= %8.2f",sqrt(x*x+y*y+z*z));
myLabel.text = [NSString stringWithFormat:#"%8.2f", sqrt(x*x+y*y+z*z)];
}];

Related

Using accelerometer for animation and output?

i'm new to xcode and objective c, so be indulgent :)
i wrote an app where i can move a small ball over the display using the accelerometer.
in addition i want to output the accelerometer data on the display.
the problem is, when i want to output the data the ball won't move.
thanks for help!
xLabel.text = [NSString stringWithFormat:#"x: %f.02", acceleration.x];
yLabel.text = [NSString stringWithFormat:#"y: %f.02", acceleration.y];
zLabel.text = [NSString stringWithFormat:#"z: %f.02", acceleration.z];
Here's the initializing code:
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer]; //Share reference
accel.delegate = self;
accel.updateInterval = 1.0f / 60.0f;
That may be because you trying to both the tasks on main thread which is not possible simultaneously.
I think you can use Core animation (which uses its own thread to perform its operations) to move object instead of directly changing frame of the object (which requires main thread).

Game Center Integration for iPhone game?

Im a beginner for developing IOS applications mainly games. I have the game completed and have submitted it to the app store. In the mere future I want to submit an update which will include game center, primarily leader boards for scores (all time, monthly, weekly, and today). I'm having trouble understanding how to integrate the completed game with game-center. Another part that is unclear to me is what do I write in the code and how does gamekit framework know which number (score) to submit to game center. If anyone could provide detailed information I'd greatly appreciate it. Thanks!
here you have a sample project
http://developer.apple.com/library/ios/#samplecode/GKTapper/Introduction/Intro.html
To send the score you have this function, score is the score, category is the name of the leaderboard you configure on itunes connect.
- (void) reportScore: (int64_t) score forCategory: (NSString*) category {
GKScore *myScoreValue = [[[GKScore alloc] initWithCategory:category] autorelease];
myScoreValue.value = score;
[myScoreValue reportScoreWithCompletionHandler:^(NSError *error){
if(error != nil){
NSLog(#"Score Submission Failed");
} else {
NSLog(#"Score Submitted");
}
}];
}
You have to use this function to send the score when your player is killed, you don't have to track if it has been the highest, but you can track if it's greater than 0;
This tutorial uses the sample project functions in his own project, take a look, it includes sending points and achivements
http://maniacdev.com/2011/05/tutorial-game-center-basics-leaderboards-and-achievements/
Game Center is available since iOS SDK 4.1
1) Open the Xcode Help.
2) On the top you should see a navigation bar, which should say "Documentation" section and move your mouse to where it says "iOS 5.1 Library"(in my case).
3) Now, move your mouse over "Networking & Internet" and click on it.
4) You now should have a list of available APIs.
After that just look around for the APIs you want, like Leaderboards, and achievements.
According to your requirements you should look for things like GKLeaderboards, and anything else you are interested in. Those documentations should link to other documentations you would need. You can find the GKLeaderboards documentation on web
Edit: The game which you developed would be showing some score to the player after each instance of the Game. Post that score to the function - (void) reportScore: (int64_t) score forCategory: (NSString*) category eg. [self.gameCenterManager reportScore:yourscore forCategory: #"yourgamecategory"];
For the GameCenterManager.h and GameCenterManager.m from this link
update score to game center use this routine.
- (void) reportScore: (int64_t) score :(NSString*) YOUR_LeaderBoard_ID
{
GKScore *scoreReporter = [[GKScore alloc] initWithCategory:YOUR_LeaderBoard_ID];
scoreReporter.value = score;
scoreReporter.context = 0;
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil)
{
IsConnectFail = true;
}else{
IsConnectFail = false;
}
}];
}

Why am I getting 0 degrees from magneticField property the whole time?

I'm trying to get the device's declination from the magnetic North in degrees, by relying solely on the device's magnetometer. This is the code I've written but I just get 0 degrees.. What am I doing wrong ?
CMMotionManager *motionManager;
motionManager = [[CMMotionManager alloc] init];
[motionManager startDeviceMotionUpdates];
CMDeviceMotion *deviceMotion;
deviceMotion = [[CMDeviceMotion alloc] init];
while(!self.stopButtonPressed)
{
double x = motionManager.deviceMotion.magneticField.field.x;
double y = motionManager.deviceMotion.magneticField.field.y;
double degrees = asin(y/sqrt(pow(x, 2.0) + pow(y, 2.0))) * 180.0 / M_PI ;
int degreesRounded = (int)degrees;
NSLog(#"Degrees : %i", degreesRounded);
}
It is likely that the simulator doesn't return normal values for these methods, so you will need to test on a real device.
The CLLocationManager's method, didUpdateHeading: doesn't work on the simulator, so you are probably experiencing something similar here.
Edit:
From the docs:
"The latest sample of device-motion data. (read-only)
#property(readonly) CMDeviceMotion *deviceMotion
Discussion
If no device-motion data is available, the value of this property is nil. An application that is receiving device-motion data after calling startDeviceMotionUpdates periodically checks the value of this property and processes the device-motion data."
Check to see if that property of your motion manager is nil. If it is, then you would get 0 for the magnetic field property.
Edit 2:
Instead of using startDeviceMotionUpdates, you should be using startMagnetometerUpdatesToQueue:. The docs say this:
"Magnetometer. Set the magnetometerUpdateInterval property to specify an update interval. Call the startMagnetometerUpdatesToQueue:withHandler: method, passing a block of type CMMagnetometerHandler. Magnetic-field data is passed into the block as CMMagnetometerData objects."
Docs are here.
What thread is the above code running on? If you're running it on the main thread, you probably won't get see updates to the device motion data over time. Use an NSTimer or similar mechanism to sample the motion over time, so the main thread is free to do other things (like service requests from the core motion sub-system).
Here is what I tested on a real device:
CMMotionManager *myMotionManager= [[CMMotionManager alloc] init];
myMotionManager.deviceMotionUpdateInterval = 1;
[myMotionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical toQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
double x = myMotionManager.deviceMotion.magneticField.field.x;
double y = myMotionManager.deviceMotion.magneticField.field.y;
double z = myMotionManager.deviceMotion.magneticField.field.z;
NSLog(#"Field.x= %f; Field.y = %f; Field.z= %f",x,y,z);
}];

How can i draw a compass like iphone 3gs in ios4?

I'm trying to make a view like compass in iphone 3gs or iphone4. Do you know somebody how can I start?, I can't find too much information about this issue...I only want to draw an arrow always following the north.
I'm using ios 4.0
Thanks in advance
Start heading updates with:
if([CLLocationManager headingAvailable]) {
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
// myDelegateObject is an instance of a class implementing the CLLocationManagerDelegate protocol
locationManger.delegate = myDelegateObject;
[locationManager startUpdatingHeading];
}
Implement the CLLocationManagerDelegate protocol on one of your classes -- in particular, something like:
-(void)locationManager:(CLLocationManager*)manager didUpdateHeading:(CLHeading*)heading {
// CLLocationDirection is a double typedef
CLLocationDirection headingInDegrees = heading.magneticHeading;
// you'll have to implement this in some fashion...
[myCompassViewController rotateCompassImageToHeading:headingInDegrees];
}

Audio plays well in iPhone simulator but not in iPhone

I have an app that is nearly finished but encountered an annoying problem. In the app, I want to play a sound when I tap on some object, then the object disappears. This is the piece of code I used:
In Object.h
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioServices.h>
#interface Object: UIView {
UIImageView *image;
CGPoint location;
SystemSoundID soundFileID;
}
In Object.m
- (void)initWithSound {
//a bunch of code to define the image and location
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"Sound" ofType:#"caf"];
CFURLRef soundURL = (CFURLRef)[NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID(soundURL, &soundFileID);
return self;
}
Then in my mainViewController, several objects will be created upon user's action and added to the screen at different locations with different images. Upon tapping on the object itself, it will create a sound and disappear.
In Object.m
- (void)tapped {
AudioServicesPlaySystemSound(soundFileID);
image.image = nil;
[self removeFromSuperview];
}
Everything works find in the simulator. But when I tried that in iPhone, the object disappears on tapping as expected but the sound just doesn't play. Tried on a 3G and a 3GS, both don't play the sound. I think this should work. Am I making any mistakes? Thanks for any help.
EDIT: Just think of something that I don't know related or not. I'm also using the microphone to detect sound input from the user by AVAudioRecorder. Not sure if this would affect the audio output.
Finally found where the problem is!!
It turns out that I have to I have to set up an audio session. It's just that! Obviously I need more study on the audio and video things.
Just for someone who may run into the same situation as me, here is the code I added in the viewDidLoad method:
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];
[audioSession setActive:YES error: &error];