#.완성된 모습

*먼저 지도표시와 위도, 경도 라이브러리를 위한 MapKit.framework 와 CoreLocation.framework를 추가한다.

*info.plist 에서 위치 수집을 위한 설정을 해준다.
*구글 firebase API를 사용하기위한 설치를 진행한다. (참고)
AppDelegate.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <UIKit/UIKit.h> | |
@import Firebase; | |
@interface AppDelegate : UIResponder <UIApplicationDelegate> | |
@property (strong, nonatomic) UIWindow *window; | |
@end |
AppDelegate.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "AppDelegate.h" | |
#import "ViewController.h" | |
@interface AppDelegate () | |
@end | |
@implementation AppDelegate | |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { | |
// Override point for customization after application launch. | |
//파이어 베이스 사용 설정 | |
[FIRApp configure]; | |
return YES; | |
} | |
- (void)applicationWillResignActive:(UIApplication *)application { | |
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. | |
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. | |
} | |
- (void)applicationDidEnterBackground:(UIApplication *)application { | |
NSLog(@"백그라운드 모드 진입 - "); | |
} | |
- (void)applicationWillEnterForeground:(UIApplication *)application { | |
NSLog(@"포그라운드 모드 진입 - "); | |
} | |
- (void)applicationDidBecomeActive:(UIApplication *)application { | |
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. | |
} | |
- (void)applicationWillTerminate:(UIApplication *)application { | |
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. | |
} | |
@end |
ViewController.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <UIKit/UIKit.h> | |
#import <CoreLocation/CoreLocation.h> | |
#import <MapKit/MapKit.h> | |
@import Firebase; | |
@interface ViewController : UIViewController<CLLocationManagerDelegate , MKMapViewDelegate> | |
@property (nonatomic, retain) CLLocationManager *locationManager; //로케이션 메니저 | |
@property (weak, nonatomic) IBOutlet MKMapView *mk; //지도 | |
@property (nonatomic, retain) MKPolyline *routeLine; //라인 | |
@property (nonatomic, retain) MKPolylineView *routeLineView; //라인뷰 | |
@property (strong, nonatomic) FIRDatabaseReference *ref; //파이어 베이스 | |
@property (strong, nonatomic) IBOutlet UIBarButtonItem *startButton; //위치수집 시작 | |
@property (strong, nonatomic) IBOutlet UIBarButtonItem *resetButton; //저장된 위치 삭제 | |
@end |
ViewController.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ViewController.h" | |
@implementation ViewController; | |
@synthesize locationManager ,mk ,routeLine , routeLineView , startButton, resetButton; | |
- (void)viewDidLoad { | |
[super viewDidLoad]; | |
//1.mapkitView 셋팅 : 지도에서 유저의 현재 위치 보이기,지도 설정 | |
mk.showsUserLocation = YES; | |
mk.mapType = MKMapTypeStandard; | |
mk.delegate = self; | |
//firebase db 초기화 | |
self.ref = [[FIRDatabase database] reference]; | |
//2.LocationManager 생성 + 초기화 | |
if (locationManager == nil) { | |
locationManager = [[CLLocationManager alloc] init]; | |
locationManager.desiredAccuracy = kCLLocationAccuracyBest; //지도 정확도 최상 | |
locationManager.delegate = self; // Location Receiver 콜백에 대한 delegate 설정 | |
locationManager.distanceFilter = 100; //100 meters 기준 위치 업데이트 | |
locationManager.pausesLocationUpdatesAutomatically = NO; //자동으로 멈춤 방지 | |
//지도 기본 zoom 설정 | |
CLLocationCoordinate2D loc = locationManager.location.coordinate; | |
if (CLLocationCoordinate2DIsValid(loc)) { | |
NSLog(@"Coordinate valid"); | |
MKCoordinateRegion userLoc = MKCoordinateRegionMakeWithDistance(loc, 400, 400); | |
[mk setRegion:userLoc]; | |
} else { | |
NSLog(@"Coordinate invalid"); | |
} | |
} | |
//소스에서 CLLocationManager 초기화 후 앱사용시에만 위치정보 수집을 하겠다 | |
if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { | |
NSLog(@"requestAlwaysAuthorization - "); | |
[locationManager requestAlwaysAuthorization]; | |
} | |
//백그라운드 상태에서도 위치정보 갱신을 하겠다는 코드 호출 | |
if ([locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) { | |
NSLog(@"setAllowsBackgroundLocationUpdates - "); | |
[locationManager setAllowsBackgroundLocationUpdates:YES]; | |
} | |
//Location Manager 시작하기 | |
//[locationManager startMonitoringSignificantLocationChanges]; | |
[locationManager startUpdatingLocation]; | |
//파이어 베이스 데이터 읽기 | |
[_ref observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) { | |
//db에 존재하는 경로 개수 | |
int cnt = (int)snapshot.childrenCount; | |
CLLocationCoordinate2D coordinateArray[cnt]; | |
int ii = 0; | |
//지도에 선 그리기릴 위한 CLLocationCoordinate2DMake 만들기 | |
for ( FIRDataSnapshot *child in snapshot.children) { | |
//위도 , 경도 | |
NSString *latString = [child.value valueForKey:@"lat"]; | |
NSString *longString = [child.value valueForKey:@"long"]; | |
double latDouble = [latString doubleValue]; | |
double longDouble = [longString doubleValue]; | |
coordinateArray[ii] = CLLocationCoordinate2DMake(latDouble, longDouble); | |
ii++; | |
} | |
//지도에 선 그리기 | |
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coordinateArray count:cnt]; | |
[self.mk addOverlay:polyline]; | |
self.routeLine = polyline; | |
//선 설정 | |
[self drawPoliyLine]; | |
} withCancelBlock:^(NSError * _Nonnull error) { | |
NSLog(@"%@", error.localizedDescription); | |
}]; | |
} | |
//일정 거리 이상 이동했을때 호출되는 메소드 | |
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { | |
NSLog(@"locationManager didUpdateLocations"); | |
NSLog(@"Latitude : %f", manager.location.coordinate.latitude); | |
NSLog(@"Longitude : %f", manager.location.coordinate.longitude); | |
//출발 버튼 눌렀을때 - 출발 중일때만 좌표 수집 | |
if([startButton.title isEqualToString:@"STOP"]){ | |
//위도 , 경도 | |
NSString* latS = [NSString stringWithFormat:@"%f", manager.location.coordinate.latitude]; | |
NSString* longS = [NSString stringWithFormat:@"%f", manager.location.coordinate.longitude]; | |
//좌표를 위한 key 값 : 현재시분초 | |
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init]; | |
[dateFormatter setDateFormat:@"yyyyMMddHHmmss"]; | |
NSLog(@"%@",[dateFormatter stringFromDate:[NSDate date]]); | |
NSString *datenow = [dateFormatter stringFromDate:[NSDate date]]; | |
//db 저장을 위한 객체 | |
NSDictionary*location = @{ | |
@"id":datenow, | |
@"lat":latS, | |
@"long":longS | |
}; | |
//현재 좌표 파이어 베이스에 저장 | |
[[self.ref child:datenow] setValue:location]; | |
} | |
} | |
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay{ | |
if(overlay == self.routeLine) | |
{ | |
if(nil == self.routeLineView) | |
{ | |
[self drawPoliyLine]; | |
} | |
return self.routeLineView; | |
} | |
return nil; | |
} | |
//선그리기 - 초기화 및 셋팅 | |
-(void) drawPoliyLine { | |
// create an MKPolylineView and add it to the map view | |
self.routeLineView = [[MKPolylineView alloc]initWithPolyline:self.routeLine]; | |
self.routeLineView.strokeColor = [UIColor redColor]; | |
self.routeLineView.lineWidth = 3; | |
} | |
//location 오류 | |
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { | |
NSLog(@"Cannot find location"); | |
} | |
//출발 - 정지 토글 버튼 | |
- (IBAction)startButtonAction:(id)sender { | |
NSLog(@"startButtonAction"); | |
if([startButton.title isEqualToString:@"START"]){ | |
[startButton setTitle:@"STOP"]; | |
}else if([startButton.title isEqualToString:@"STOP"]){ | |
[startButton setTitle:@"START"]; | |
} | |
} | |
//파이어 베이스 db 데이터 전체 삭제 | |
- (IBAction)resetButtonAction:(id)sender { | |
NSLog(@"resetButtonAction"); | |
[_ref removeValue]; | |
} | |
@end |
Main.Storyboard

예제파일
WhereDoILive.zip
0.02MB
전체거리 계산 예제
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//*두 좌표 거리 계산 | |
//1.시작 지점 | |
Pin *firstPin = [self.allPins objectAtIndex:0]; | |
CLLocationCoordinate2D firstCoordinate = firstPin.coordinate; | |
CLLocation *firstLocation = [[CLLocation alloc] initWithLatitude:firstCoordinate.latitude longitude:firstCoordinate.longitude]; | |
//2.끝 지점 | |
Pin *secondPin = [self.allPins objectAtIndex:1]; | |
CLLocationCoordinate2D secondCoordinate = secondPin.coordinate; | |
CLLocation *secondLocation = [[CLLocation alloc] initWithLatitude:secondCoordinate.latitude longitude:secondCoordinate.longitude]; | |
//3.double 타입 - 출력 | |
CLLocationDistance distance = [secondLocation distanceFromLocation:firstLocation]; | |
NSString *distanceS = [NSString stringWithFormat: @"%.2f 미터", distance]; | |
NSLog(@"거리 : %@" , distanceS); | |
/*****************************************/ | |
//*전체 거리 계산 | |
if (self.allPins.count < 2) { | |
NSLog(@"계산할 지점이 없습니다."); | |
}else { | |
CLLocation *newLoc; //첫 지점 | |
CLLocation *oldLoc; //다음 지점 | |
CLLocationDistance distance = 0.0; //전체 거리 | |
for (int i = 0; i < (self.allPins.count -1); i++) { | |
//첫지점 | |
Pin *firstPin = [self.allPins objectAtIndex:i]; | |
CLLocationCoordinate2D firstCoordinate = firstPin.coordinate; | |
newLoc = [[CLLocation alloc] initWithLatitude:firstCoordinate.latitude longitude:firstCoordinate.longitude]; | |
//두번째지점 | |
Pin *secondPin = [self.allPins objectAtIndex:i+1]; | |
CLLocationCoordinate2D secondCoordinate = secondPin.coordinate; | |
oldLoc = [[CLLocation alloc] initWithLatitude:secondCoordinate.latitude longitude:secondCoordinate.longitude]; | |
//3.전체거리에 + | |
distance += [oldLoc distanceFromLocation:newLoc]; | |
} | |
//4.출력 | |
NSString *distanceS = [NSString stringWithFormat: @"%.2f 미터", distance]; | |
NSLog(@"전체거리 : %@" , distanceS); | |
} |
WhereDoILive.zip
0.02MB
참고 1. : 폴리라인
참고 2. : iOS :지도에 매력적인 경로 그리기
'아이폰 개발 > ios 개념&튜토리얼' 카테고리의 다른 글
Ios push 기초 with Firebase (1) | 2020.08.01 |
---|---|
Ios CoreData 간단한 예제로 배우기 (0) | 2020.07.30 |
SQLite 응용 (0) | 2020.07.29 |
SQLite 기초 (0) | 2020.07.29 |
MKMapView 와 CLLocationCoordinate 이용해서 지도에 경로 표시하기 (0) | 2020.07.28 |