
Under the wing of an airplane sings about something

If you carefully look at the image on the left, it is easy to determine the location of the author.
It is enough to take the compass and atlas of Russia.
Set the leg of the compass in Sasovo and draw a circle with a radius of 103 km.
Then draw another circle (the center is in Sormovo) with a radius of 141 km.
I will be at the intersection. Achtung! Fire!
I’ll tell you how I wrote an altimeter application, interesting for air travelers. No ads. No money. Clean code.
My friend, a careless rider, often flies Moscow-Geneva and back
And he asked me to do him a favor. Make an iPhone application that reports on the current altitude. And something else informative.
I guessed that the plane looked like my village beyond Krasnoyarsk. That is, the Internet is completely absent. I decided to cram directly into the application a list of legal airports in the world and lingerie galleries. What else to do on board an airplane, if not contemplation of the beautiful or the distant?
GPS enable
The modern iPhone GPS sensor stores planetary coordinates and altitude. The accuracy of the height measure depends on various factors, but is sometimes good enough - less than 6 yards. In this case, you can, by turning on the application, jump from the roof of a skyscraper and observe online a change in height. ️Warning! This may be hazardous to your health️.
Turning on the GPS tracker in the application takes 7 lines
CLLocationManager *locationManager; // это в заголовке класса типа ViewController
// Do any additional setup after loading the view, typically from a nib.
locationManager = [CLLocationManager new];
[locationManager requestWhenInUseAuthorization];
[locationManager requestAlwaysAuthorization];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
After that, two functions appear in your class that regularly receive messages from the GPS sensor.
One function comes to life when the sensor is working, and the second - when the sensor is broken or does not see satellites.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation *currentLocation = [locations objectAtIndex:0];
NSLog(@"GPS Tracking %f", currentLocation.verticalAccuracy);
[playView updateHeight:currentLocation.altitude]; // это личное
}
-(void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"GPS Error %@, denied=%d", error.description, error.code==kCLErrorDenied);
}
Do you think everything will work now? Nope
For the application to work, the above was not enough. Nothing came into the didUpdateLocations function. And, in general, she was not called. And the didFailWithError function did not breathe.
It turned out in the application settings, you need to enable two checkmarks, (we follow the hand, rraz) - Targets-> Capabilities-> Background modes->

After these magical actions, the application worked, yo-ho-ho!
How you will now process messages is a purely individual matter.
App design
I decided to show in portrait mode
- Large numbers in height;
- Small numbers indicate the accuracy of measurements;
- A beautiful blue graph - every second height tracking;
- A very beautiful burgundy schedule - every minute tracking height.
Well, yes, the burgundy point is added to the chart 1 time per minute. There are 25 such points in total, so the old points are forgotten and not drawn when new ones appear. Is everything simple? Yes, and vividly so.
Of course, in landscape mode, the big numbers go beautifully and a graph of the entire session appears.
Added buttons to stop tracking and continue or start tracking again .
These buttons are necessary because the tracking mode eats up the battery (I really didn’t notice this) and lights up an unpleasant blue background at the top of the screen when the application goes into sleep or inactive mode.
Beautiful graphics
To draw graphs, I applied the following trick. Started up
pictures. I

called segments between graph points with the UIImageView type.
And transformed the segments according to the law of linear algebra, let its name be holy.
for (int k=0;k<24-1;k++) {
UIImageView *p1 = [pointsQ objectAtIndex:k];
UIImageView *p2 = [pointsQ objectAtIndex:k+1];
UIImageView *p = [linesQ objectAtIndex:k];
float x1 = p1.center.x;
float x2 = p2.center.x;
float y1 = Y0 - (q2[k]-hmin)*dh;
float y2 = Y0 - (q2[k+1]-hmin)*dh;
float l2 = hypot((x2-x1),(y2-y1));
float cDy = 1.0/l2;
float a = -(x2-x1)*2.0/cellDy;
float c = -(y2-y1)*cDy;
float b = -(y2-y1)*2.0/cellDy;
float d = (x2-x1)*cDy;
float tx = 0.0;
float ty = 0.0;
p.alpha = (q1[k]*q1[k+1]) ? 1.0 : 0.0;
p.center = CGPointMake(0.5*(x1+x2), 0.5*(y1+y2));
p.transform = CGAffineTransformMake(a, b, c, d, tx, ty);
}
Here p1, p2 are the points between which it is necessary to draw a segment p, q1 [x] is the array of flags of the height value (0-no value), q2 [x] is the array of height values, cellDy is the image size in pixels. Y0 is the shift of the graph in height. Pervert, you say? Yes, I love such tricks, what to hide there, I remember the times of the games of the mind.
The last three operators can be replaced with one, but this is homework.
Homework answer
p.transform = (q1[k]*q1[k+1]) ? CGAffineTransformMake(a, b, c, d, 0.5*(x1+x2), 0.5*(y1+y2)) : CGAffineTransformMakeScale(0, 0);

Here is such a flight. With a lot of data, I interpolate the elevation values by 40 key points. I checked the work for 36 hours in a row, I think no one will surpass my record.
List of airports
The list of airports must be placed in the application so that it is available at any time, regardless of the availability of the Internet.
I took the data about the airdromes from the first link from the request free airports list xml
Packed the list in airports.sql file (less than 9000 units), added the file to the project, when I start the application, I read and load airports.sql into the Airport structure
#import
#import
@interface Airport : NSObject
{
}
@property (nonatomic) NSInteger db_id;
@property (nonatomic) NSString *name;
@property (nonatomic) NSString *city;
@property (nonatomic) NSString *country;
@property (nonatomic) NSString *iata;
@property (nonatomic) NSString *icao;
@property (nonatomic) double latitude;
@property (nonatomic) double longitude;
@property (nonatomic) double altitude;
@property (nonatomic) int timezone;
@property (nonatomic) NSString *dst;
@property (nonatomic) NSString *timezone_name;
@property (nonatomic, retain) CLLocation* location;
@property (nonatomic,readonly) double distanceFromHere;
- (id) initWithSQLStatement:(sqlite3_stmt *) selectstmt;
- (double) distanceFromLocation:(CLLocation*)location;
/*
id integer,
name text,
city text,
country text,
iata text,
icao text,
latitude float,
longitude float,
altitude float,
timezone integer,
dst text,
timezone_name text
*/ это структура базы данных, если чо забыл
@end
The calculation of the distance from the current position to any airport was made by Apple long before me
- (double) distanceFromLocation:(CLLocation*)location
{
_distanceFromHere = [self.location distanceFromLocation:location];
return _distanceFromHere;
}
Then I add sorting and list the ten nearest airports (UITableViewController).
I was surprised to find that the nearest airfield is not in Nizhny Novgorod, but in Sasovo, Ryazan province. Here are the miracles. I was in this Sasovo flight school in 1991. Nicolas D. and I made the YAK-52 simulator on the AT-286. 12 frames per second, assembler, I remember vaguely, Pascal, assembler again, Chassis-Royal cocktail .
List of lingerie salons
Initially, I wanted to stick photos and fake names of virtual courtesans of the largest cities in Europe. You’re flying, you see, but the list is being updated. But he didn’t dare - suddenly the Review Team is able to change the height, they will ban me for my bare boobs. Limited to beautiful linen.

Added by the same algorithm as airfields.
However, the quest turned out, the chip only works at a height above 9000 meters.
Butting with the store

The application was quickly made (as part of a useless event, 6 applications in 6 weeks ) and was approved for a long time in the store. A very long time, almost two months.
The ambush was that the user should be warned with the following phrase
Continued use of GPS running in the background can dramatically decrease battery life
The first time the application slowed down - they said let's fix it.
I inserted beautifully
️ Continued use of GPS running in the background can dramatically decrease battery life️
And he turned out to be an idiot. These yellow special characters are prohibited.
I had to wait another 10 days, and then another 10 ...
And today they approved .
Application check
Yes, I had to fly. Not for me, of course, oats are expensive today. The problem became clear. In the aisle chairs, the application often does not work. GPS, a scoundrel, does not see satellites.
I was comforted by the fact that there was a (wonderful?) Reason to get acquainted with a (beautiful?) Companion at the window.
At the porthole, satellites and companions are visible wonderfully.