
æè¿ãç§ã¯ãã°ãã°è³ªåãèŠãŸãïŒ
iOSã¯ãã¢ããªã±ãŒã·ã§ã³ãæå°åãããããŒã¿ããµãŒããŒã«éä¿¡ãããšãã«ãžãªãã±ãŒã·ã§ã³ã§åäœã§ããŸããïŒ
ããã¯æ¬åœã«å¯èœã§ããããŸã£ããé£ããããšã§ã¯ãããŸããã
ãã¬ãã¥ãŒèšäº
ã«åãã
æ¹æ³ ã
ãã ããå€ãã®å Žåãã¿ã¹ã¯ã¯ããè€éã§ããããã®åéã§ããªãã®çµéšãããããããã®çµéšãå
±æããããšã«ããŸããã
ããã€ãã®è©³çްãåŸãããã«ãèªè»¢è»ãã©ãã«ãŒãäœæããã¿ã¹ã¯ã«çŽé¢ããããšãææ¡ããŸããã ãŠãŒã¶ãŒåŽããèŠããšã次ã®ããã«ãªããŸãã
- ã¢ããªã±ãŒã·ã§ã³ãããŠã³ããŒããã
- èµ°ã
- ç»é²ãã
- ç§ã¯åœŒããå°ããå Žæãã¯ãªãã¯ããŸã
- ç§ã¯éããŸã
- ä¹ã
- èµ°ã
- çµæãèŠã
psæçµã³ãŒãã¯ãã¡ãã§ãã
éçºã«ã¯ã3ã€ã®äž»èŠãªäœæ¥é åããããŸãã
- å°çããŒã¿ã䜿çšããäœæ¥ã®å®å®æ§ã
ãŠãŒã¶ãŒãã¢ããªã±ãŒã·ã§ã³ãèµ·åãæå°åããŸãã¯å®å
šã«éãã-ã¢ããªã±ãŒã·ã§ã³ã¯ããŒã¿ãåŠçããå¿
èŠããããŸãã - ããããªãŒç¯çŽã
ããããã远å ã®èª¬æã¯å¿
èŠãããŸããã
ãšããã§ãããã¯ä»äºã®æãé£ããéšåã§ãã - é©åãªããŒã¿åŠçã
ããŒã¿ãæäœããã«ã¯ããã¹ããšãããã°ãå¿
èŠã§ãã
ãããŒãžã£ãŒã®åæå
æåã«ã CLLocationManagerã®äœ¿ãæ
£ããäœæ¥ãèŠãŠã¿ãŸãããã
- ãããŒãžã£ãŒãäœæããŸãã
- ã€ãã³ãã賌èªããŸãã
- äœçœ®æ
å ±ã®å€åã«å¯Ÿå¿ããããã«ãããŒãžã£ãŒãéå§ããŸãã
æå°ã³ãŒãimport CoreLocation final class LocationService: NSObject, CLLocationManagerDelegate { private let locationManager = CLLocationManager() override init() { super.init() locationManager.delegate = self locationManager.startUpdatingLocation() } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { } }
ãã ãããããæ©èœãããã«ã¯ããã®å Žæã«é¢ããæ
å ±ã䜿çšã§ããããšã確èªãããŠãŒã¶ãŒç¢ºèªãå¿
èŠã§ãã
...ãŸãã¯ç§ã¯æš©å©ãæã£ãŠããŸããïŒ
iOSã¯ããžãªãã±ãŒã·ã§ã³ãæäœããããã®2ã€ã®æš©éãæäŸããŸãã
- requestWhenInUseAuthorization-ã¢ããªã±ãŒã·ã§ã³ãã¢ã¯ãã£ããªãšãã«å Žæã®æŽæ°ã«é¢ããæ
å ±ãåãåãããšãã§ããŸãã
- requestAlwaysAuthorization-ããã«ãã¢ããªã±ãŒã·ã§ã³ãã¢ã¯ãã£ãã§ãªã/éããŠãããšãã«ã CLLocationManager APIã€ãã³ããåä¿¡ããæ©äŒãååŸããŸã ã
ãã®ããšãããããã¯ã°ã©ãŠã³ãã§ã®ãžãªãã±ãŒã·ã§ã³ã®æäœã¯requestAlwaysAuthorizationæš©éã§ã®ã¿å®è¡ã§ãããšèãããããããŸãã-ããã¯ããã§ã¯ãããŸããã
ãããšåãããã«ã requestAlwaysAuthorizationã§ã¯ããç®±ããåºããŠãããã¯ã°ã©ãŠã³ãã§éãã«äœæ¥ããããšã¯ã§ããŸããã å°åã人æ°ã®ããå ŽæãéèŠãªåããªã©ãæ±ãããšã§ãã
äžèšã®ã³ãŒãããããžã§ã¯ãå
ã«ããå Žåã requestWhenInUseAuthorizationïŒïŒãŸãã¯requestAlwaysAuthorizationïŒïŒã¡ãœãããåŒã³åºããŠãããŠãŒã¶ãŒã«æš©éã®èŠæ±ã«é¢ããã¢ã©ãŒãã¯è¡šç€ºãããŸããã
ãããè¡ãã«ã¯ã察å¿ããããŒNSLocationAlwaysUsageDescription / NSLocationWhenInUseUsageDescriptionã® info.plistã«ã¡ãã»ãŒãžã®èª¬æããã¹ãã远å ããå¿
èŠããããŸãã
ããã§ããŠãŒã¶ãŒãæš©å©ã確èªããåŸããžãªãã±ãŒã·ã§ã³ãæäœã§ããŸãã
ç§ãã¡ã¯ããã¯ã°ã©ãŠã³ãã§åããŠããŸã
ã¢ããªã±ãŒã·ã§ã³ãããã¯ã°ã©ãŠã³ãã§äœçœ®æ
å ±ãåŠçããã«ã¯ã2ã€ã®ããšãè¡ãå¿
èŠããããŸãã
- CLLocationManagerã§èšå®
allowsBackgroundLocationUpdates = true
- ããã¯ã°ã©ãŠã³ãã¢ãŒãã®ãã©ã¡ãŒã¿ãŒã«è¿œå ããŸãïŒãããã¯ã°ã©ãŠã³ãã¢ãŒã->å Žæã®æŽæ°ãïŒã ããã§ãªãå ŽåãäŸå€ãã¹ããŒãããŸãã
ãã¹ãŠãã¢ããªã±ãŒã·ã§ã³ã¯ãžãªãã±ãŒã·ã§ã³ã䜿çšããŠããã¯ã°ã©ãŠã³ãã§åäœãããããã¯ãŒã¯èŠæ±ãªã©ãéä¿¡ã§ããŸãã
äœããããŸããããªãã£ã
ã¢ããªã±ãŒã·ã§ã³ãæå°åãããŠãŒã¶ãŒããã°ããã®éã·ã¹ãã ã®èгç¹ããåããªããŸãŸã«ãªããšããžãªãã±ãŒã·ã§ã³ã¯åæ¢ããããã«ãã£ãŠã¢ããªã±ãŒã·ã§ã³ã忢ããŸãã
åé¡ã¯ãããã©ã«ãã§ã¯CLLocationManagerãäžæåæ¢ã䜿çšããŠpausesLocationUpdatesAutomaticallyããžãªãã±ãŒã·ã§ã³ããããšã§ã ã ãããŠããã®ãã©ã¡ãŒã¿ãŒã¯èŠãç®ã»ã©åçŽã§ã¯ãããŸããã
- ã¢ããªã±ãŒã·ã§ã³ãèµ·åããåãå§ããŸããã ã¢ããªã±ãŒã·ã§ã³ã¯åäœããŠããŸãã
- ã¢ããªã±ãŒã·ã§ã³ãæå°åããç§»åãç¶ããŸããã ã¢ããªã±ãŒã·ã§ã³ã¯åäœããŠããŸãã
- ç§ã¯å人ã«äŒãã圌ãšè©±ãããšããããã ã¢ããªã¯ãŸã å®è¡äžã§ãã
ãããŠãããæç¹ã§æ©èœããªããªããŸãã
ãçè§£ã®ãšãããäžæåæ¢ãéå§ããããã°ããããŠãããã¯ã°ã©ãŠã³ãã«ããã¢ããªã±ãŒã·ã§ã³èªäœã®äœæ¥ã忢ããŸããã ããã¯äžæåæ¢ãªã®ã§ãããªãè«ççã§ãã
ç§ã¯åãç¶ããŸããããLocationManagerã¯ãŸã äžæåæ¢ãããŠããŸããã ãããŠãç§ãã¢ããªã±ãŒã·ã§ã³ãèªåã§ãããã€ãããŸã§ã圌ã¯äžæåæ¢ãããŸãŸã§ãã
ãããã£ãŠãã·ã¹ãã ã¯ãã忢ãåã«äœæ¥ããå¿
èŠãããå Žåã«ããããªãŒé»åãç¯çŽããããšããŸãã
äžæåæ¢ãå¿
èŠãªå Žåã¯psããã§ããã¢ããªã±ãŒã·ã§ã³ãç§»åã®æåŸãŸã§åäœããå¿
èŠãããå Žåã¯ããžãªãã±ãŒã·ã§ã³ã§äœæ¥ããŠãããactivityTypeãã§é©åãªã¿ãŒã²ãããæå®ããããšã«ãããã·ã¹ãã ããã®ç¶æ
ãããé©åã«å€æã§ããããã«æ¯æŽã§ããŸãã
ããã¯ç§ãã¡ã«ãšã£ãŠå
·äœçãªåé¡ãªã®ã§ãLocationManagerã®äžæåæ¢ããªãã«ããŠãã ããã
pausesLocationUpdatesAutomatically = false
殺ããªãã§ ã€ã¯ã³ã»ãã¡ã¬ããã ãŠãŒã¶ãŒåïŒ
以åã requestAlwaysAuthorizationãžãªãã±ãŒã·ã§ã³ã¢ã¯ã»ã¹æš©ã«ã€ããŠã¯æ¢ã«èšåããŸããã ãŸãã CLLocationManager APIã€ãã³ããåä¿¡ã§ããããã«ããŸãã ããã¯ã°ã©ãŠã³ããšã¢ã³ããŒãç¶æ
ã®äž¡æ¹ãåä¿¡ããŸãã åŸè
ã®å Žåãã·ã¹ãã ã¯ã¢ããªã±ãŒã·ã§ã³ãåèµ·åããŠæ°ããã€ãã³ããé
ä¿¡ã§ããŸãã äŸïŒ
locationManager.startMonitoringSignificantLocationChanges() â locationManager.startMonitoringVisits() â locationManager.startMonitoring(for: CLRegion) â
ããã䜿çšãããã®ã§ãã 䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã匷å¶çµäºããå Žåãã§ããã ãæ©ãäœæ¥ã«æ»ãå¿
èŠããããŸãã ç§ã®å Žåãå°åã«ã¯ååŸã®å¶éããããããæãé©ããŠããã®ã¯startMonitoringSignificantLocationChangesã§ãã äž»ãªããšã¯ ã CLLocationManagerã®èµ·åãšæ§æãå¿ããªãããšã§ã ã
å®å
šãªã³ãŒã import CoreLocation final class LocationService: NSObject, CLLocationManagerDelegate { private let locationManager = CLLocationManager() override init() { super.init() locationManager.delegate = self locationManager.requestAlwaysAuthorization() locationManager.allowsBackgroundLocationUpdates = true locationManager.pausesLocationUpdatesAutomatically = false locationManager.startUpdatingLocation() locationManager.startMonitoringSignificantLocationChanges() } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { } }
ãããïŒ ã¢ããªã±ãŒã·ã§ã³ã¯ããã¯ã°ã©ãŠã³ãã§åäœããã¢ããªã±ãŒã·ã§ã³ã¯åèµ·åãããžãªãã±ãŒã·ã§ã³ã§åäœãããããã¯ãŒã¯ã§åäœã§ããŸãã ããã€ã¹ãããã®ãããªã¢ã¯ãã£ããã£ããã£ãå Žåã圌ããåé€ããŸãã
ããããªãŒç¯çŽ
ãšãã«ã®ãŒæ¶è²»ã®çµ±èšãéããšã99.99ïŒ
ã®ç¢ºçã®ã¢ããªã±ãŒã·ã§ã³ããªãŒããŒãšãªããæ®å¿µãªãããç¯çŽã«ã¯ãªããŸããã ãããã£ãŠãæé©åãè¡ããŸãã
ãšã©ãŒ
ããããªãŒæ¶è²»ã¯ã CLLocationManagerããã®å¿
èŠãªãšã©ãŒã®åœ±é¿ã倧ããåããŸãã
æãæ£ç¢ºãªããŒã¿ãèŠæ±ã§ããŸãããçŽ10ã¡ãŒãã«ã3ããã¡ãŒãã«ãããã³tpïŒ kCLLocationAccuracy * ïŒã®èª€å·®ã§èŠæ±ã§ããŸãã
ãããã£ãŠãå¿
èŠãªããŒã¿å質ãé«ãã»ã©ãããããªãŒã®æ¶è²»éãå€ããªããŸãã
ãããã£ãŠã100må
ã«ååãªãšã©ãŒãããå Žåãæå€§å質ãååŸããå¿
èŠã¯ãããŸããã
ããã«è峿·±ãã®ã¯ãäœå質ãå¿
èŠãªå Žåãã·ã¹ãã ãæåŸ
以äžã®çµæãããããå¯èœæ§ãé«ãããšã§ãã ãããã£ãŠãå®éã«å¿
èŠãªãã®ããããšã©ãŒãèŠæ±ããªãããšãäžå¯æ¬ ã§ãã
ps requiredã¯æå¹ãšããæå³ã§ã¯ãããŸããã
æ§æ
ããã«ã distanceFilterãšallowDeferredLocationUpdatesã«ã€ããŠèããã°ãããããªãŒã®æŠãã«åã€ããšãã§ããŸãã
- distanceFilterã䜿çšãããšãè·é¢ãã¡ãŒãã«åäœã§èšå®ã§ããŸãããã®éããã€ã³ããããã€ã³ããžã®äœçœ®æ
å ±ã®å€æŽã¯å¿
èŠãããŸããã ç¯çŽã¯ããã»ã©å€§ãããããŸããããç¯çŽã§ãã
- é
å»¶éç¥ïŒallowDeferredLocationUpdatesïŒã«ãããã·ã¹ãã ã¯ãã®è£éã§ããŸãã¯æå®ãããåºæºã«åŸã£ãŠæ
å ±ãé
ä¿¡ã§ããŸãã
åºæºã¯è·é¢ãšæéã§ãã
ããšãã°ãæåŸã®ãã€ã³ããåä¿¡ãããç¬éããããã€ã³ãã5å以å
ã«å°çããªãå Žåãã¢ããªã±ãŒã·ã§ã³ããžãã¯ã¯äžæããŸããããã·ã¹ãã ã¯ããããäžåºŠã«é
ä¿¡ããŸã ã
åºæºã¯5åã«çããæéã§ãã ãã®æç¹ã§å¥ã®ã¢ããªã±ãŒã·ã§ã³ããžãªããŒã¿ãèŠæ±ãããšãã·ã¹ãã ã¯åæã«çޝç©ãã€ã³ããæäŸããå ŽåããããŸãã CLLocationManagerã®æ§æã«ã¯ãèŠããŠããå¿
èŠã®ããå€ãã®é¢é£ããå¶éããããŸãã
æ¬åœã«å¿
èŠãªãšãã«ããŒã¿ãæäœãã
ç§ãã¡ã®ç®æšã¯ãã€ã¯ãã©ãã«ãŒã§ããããšã瀺ããŸããã çŸæç¹ã§ã¯ãããŒã¿ãå¿
èŠãã©ããã«é¢ä¿ãªããåžžã«ããŒã¿ãåŠçããŸãã äžæåæ¢ã®ããããžãªãã±ãŒã·ã§ã³ã忢ã§ããŸããã
1ã€ã®ãœãªã¥ãŒã·ã§ã³ã¯ãæ
è¡äžããã³ãã®ä»ã®æéã«å¿
èŠãªããŒã¿å質ã倿ŽããŸãã æé«ã®ããŒã¿ãšææªã®ããŒã¿ã®å·®ã¯ã»ãŒ4åã§ãã
ã¹ããŒããã«CLLocationManagerèšå®ã®å€æŽ func setActiveMode(_ value: Bool) { if value { locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters locationManager.distanceFilter = 10 } else { locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers locationManager.distanceFilter = CLLocationDistanceMax } }
çŸåšã§ã¯ããŠãŒã¶ãŒãèªè»¢è»ã«ä¹ããšãã远跡ããã ãã§ãã ããã«ã¯ã CoreMotionã®CMMotionActivityManagerã䜿çšã§ããŸãã
ã¢ã¯ãã£ããã£ã¿ã€ãã远跡ãã motionManager.startActivityUpdates(to: .main, withHandler: { [weak self] activity in self?.setActiveMode(activity?.cycling ?? false) })
å®å
šãªLocationServiceã³ãŒã import CoreLocation import CoreMotion final class LocationService: NSObject, CLLocationManagerDelegate { private let locationManager = CLLocationManager() private let motionManager = CMMotionActivityManager() override init() { super.init() locationManager.delegate = self locationManager.requestAlwaysAuthorization() locationManager.allowsBackgroundLocationUpdates = true locationManager.pausesLocationUpdatesAutomatically = false setActiveMode(true) locationManager.startUpdatingLocation() locationManager.startMonitoringSignificantLocationChanges() motionManager.startActivityUpdates(to: .main, withHandler: { [weak self] activity in self?.setActiveMode(activity?.cycling ?? false) }) } func setActiveMode(_ value: Bool) { if value { locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters locationManager.distanceFilter = 10 } else { locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers locationManager.distanceFilter = CLLocationDistanceMax } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { } }
ãšãã«ã®ãŒæ¶è²»éãšçšŒåæéã
ã¿ã€ãAïŒæå€§å質
ã¿ã€ãBïŒæå€§å質+ãé
ã¿ã€ãCïŒææªå質+ãé
ã¿ã€ãDïŒé©çšãªã
ãŸã æ¹åã®äœå°ã¯ãããŸããïŒ ãã¡ããã ãã®ã¢ãããŒãã¯ããã¹ãŠã®ãžãªãã±ãŒã·ã§ã³ãããã¯ã°ã©ãŠã³ãã§åŠçããããšãéèŠãªå Žåã«å¿
èŠã§ãã ããã«ããªãã®æ³ååã«äŸåããŸãã
iOS 10以éã®å ŽåãInfo.plistã«NSMotionUsageDescriptionãç»é²ããå¿
èŠããããŸã <key>NSMotionUsageDescription</key> <string>$(PRODUCT_NAME) motion use.</string>
ãã±ãŒã·ã§ã³åŠçã®ç¢ºèª
ã¢ããªã±ãŒã·ã§ã³ã確èªããå¿
èŠããããŸãã ãæ
è¡ããæžãéçšã§è±èœããã®ã¯åŸçã§ã¯ãããŸããã ã¯ãããã®ã¢ãããŒãã§ã®ãããã°ã¯å¿ããããŸãã
幞ããªããšã«ãAppleã¯GPXãã¡ã€ã«ã®äœ¿çšãèš±å¯ããŠããŸãïŒãã®å Žåãå®éã®ããã€ã¹ã¯å¿
èŠãããŸããïŒã
ç§»åã«ãŒããçæãããµãŒãã¹ãéžæããgpxã«ãã©ãŒã ã®ãã¡ã€ã«ãä¿åããŸãã
ãã¡ã€ã«äŸ <?xml version="1.0"?> <gpx version="1.1" creator="Xcode"> <wpt lat="54.91148" lon="83.07381"/> <wpt lat="54.90792" lon="83.07243"/> </gpx>
ã¹ããŒã ã®èšå®ã§ãžãªãã±ãŒã·ã§ã³ã·ãã¥ã¬ãŒã·ã§ã³ãæå¹ã«ããGPXãã¡ã€ã«ãããŒãããŸãã ç®çã®ã·ãã¥ã¬ãŒã·ã§ã³ãéžæãããããã°ã䜿çšããŸãã çµè«ã®ä»£ããã«
æ®å¿µãªãããé¢çœãããšãæçœãªããšãæžãã®ã¯é£ããã®ã§ãå€ãã®ç¹ã¯ãããŸããã
- ã¢ããªã±ãŒã·ã§ã³ãããã¯ã°ã©ãŠã³ãã§ãåèµ·åããããšããŠãŒã¶ãŒã¯åœŒããæ®ºããããšãã§ããªããªããŸãã
- ã¢ããªã±ãŒã·ã§ã³ãããã¯ã°ã©ãŠã³ãã«ãããšãã«ãžãªãã±ãŒã·ã§ã³ãäžæåæ¢ãããå Žåãããã·ã¥éç¥ããªãŒãžã§ã³ãªã©ã䜿çšããŠãžãªãã±ãŒã·ã§ã³ãäžæåæ¢ããããšã¯ã§ããŸããã åãããšããããŒãžã£ãŒã®åèµ·åã«ãåœãŠã¯ãŸããŸãã ããã¯ãã¢ããªã±ãŒã·ã§ã³ã®ãå転ãåŸã«ã®ã¿é©çšãããŸãã
- ãžãªãã±ãŒã·ã§ã³ã¯ãšã©ãŒãšãšãã«æ©èœããŸãã ãã£ã«ã¿ãŒã䜿çšããªãå Žåã1ãæã«ç«ã£ãŠããéã«äœçœ®æ
å ±ã«å€ãã®å€æŽãå ããããšãã§ããŸãã
- å®éã®ããã€ã¹ã§ãžãªãã±ãŒã·ã§ã³ã·ãã¥ã¬ãŒã·ã§ã³ãæå¹ã«ãããšãä»ã®ã¢ããªã±ãŒã·ã§ã³ããæ°ããããžãªãã±ãŒã·ã§ã³ã§æ©èœããŸãã ããšãã°ãã«ãŒãã
- ãžãªãã±ãŒã·ã§ã³ã®é·ãã·ãã¥ã¬ãŒã·ã§ã³ã䜿çšãããšãå®éã®ããã€ã¹ã¯ãã¹ãã£ãã¯ãããŠã·ãã¥ã¬ãŒã·ã§ã³ã®åæ¢ã忢ã§ããŸãã åèµ·åã®ã¿ã圹ç«ã¡ãŸãã
- ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšããå€ããã€ã³ãããååŸããå¯èœæ§ããããŸãã tsãèŠãã®ãå¿ããªãã§ãã ããã
- CLLocationManagerãã©ããããŠããã¹ãã®ããã«GPXãè§£æã§ããŸãã
- GPXãã¡ã€ã«ã§ã¯ãé床ããã€ã³ãåäœã§èšå®ã§ããŸãã
- äžéšã®ãªããžã§ã¯ãã®è¿ãã®GPSãæ©èœããªãå ŽåããããŸãã
- æ©å
ã¢ãŒãã§ãžãªãã±ãŒã·ã§ã³ã䜿çšã§ããŸãã
- SIMã«ãŒããªãã§ãžãªãã±ãŒã·ã§ã³ã䜿çšã§ããŸãã
psæçµã³ãŒãã¯ãã¡ãã§ãã