Вы не можете контролировать точность внутреннего MKMapView
диспетчера местоположений (который использовался для отслеживания пользователя с помощью синей точки), но вы можете создать свой собственный и использовать его для повторной центровки карты. Вот рецепт ...
В делегате расположения ядра:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
NSLog(@"User has denied location services");
} else {
NSLog(@"Location manager did fail with error: %@", error.localizedFailureReason);
}
}
Прямо перед настройкой диспетчера местоположения:
if (![CLLocationManager locationServicesEnabled]){
NSLog(@"location services are disabled"];
return;
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
NSLog(@"location services are blocked by the user");
return;
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized){
NSLog(@"location services are enabled");
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
NSLog(@"about to show a dialog requesting permission");
}
self.locationManager = [CLLocationManager new];
self.locationManager.purpose = @"Tracking your movements on the map.";
self.locationManager.delegate = self;
/* Pinpoint our location with the following accuracy:
*
* kCLLocationAccuracyBestForNavigation highest + sensor data
* kCLLocationAccuracyBest highest
* kCLLocationAccuracyNearestTenMeters 10 meters
* kCLLocationAccuracyHundredMeters 100 meters
* kCLLocationAccuracyKilometer 1000 meters
* kCLLocationAccuracyThreeKilometers 3000 meters
*/
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
/* Notify changes when device has moved x meters.
* Default value is kCLDistanceFilterNone: all movements are reported.
*/
self.locationManager.distanceFilter = 10.0f;
/* Notify heading changes when heading is > 5.
* Default value is kCLHeadingFilterNone: all movements are reported.
*/
self.locationManager.headingFilter = 5;
// update location
if ([CLLocationManager locationServicesEnabled]){
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
MKCoordinateRegion region = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
region.center = newLocation.coordinate;
region.span.longitudeDelta = 0.15f;
region.span.latitudeDelta = 0.15f;
[self.mapView setRegion:region animated:YES];
}
Поместите это в делегата. MKMapView не имеет фильтра расстояния или точности, только CLLocationManager. MKMapView имеет область охвата вокруг точки, в примере выше 0,15 градуса (0,15 * 111 км).
Документация не сообщает, откуда MKMapView
получает свои обновления. Я попробовал
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(@"newLocation %@", newLocation.timestamp);
NSLog(@"last map location %@", [NSString stringWithFormat:@"%@",[[[self.mapView userLocation] location] timestamp]]);
}
и получаю разные значения для каждого. Похоже, что MKMapView
использует свой собственный CLLocationManager
, что означает, что вы не можете установить его точность. Вы также не можете добавить своего делегата для CLLocationManager
из MKMapView
.
У меня сложилось впечатление, что единственный способ установить точность - это настроить показывать пользовательское положение как NO и создавать пользовательскую аннотацию с синей точкой, что означает повторное повторение карты вручную после публикации. Вы можете получить изображение с синей точкой из SDK с помощью экстрактора иллюстраций проекта github.
Я не знаю, упускаю ли я что-то или эта часть MKMapView
просто отстой.
To encourage better TDD. Have two testing projects and or namespeaces X.Unit.Tests & X.Integrations.Tests.
I have my DI code in my main project in a "namespace directory" (/Config) but in my integration code tests, I might just call those registries or override if I required in my base fixtures or setups.
E.g.
/Config/ServiceRegistry.cs /Config/RepositoryRegistry.cs /Config/Bootstrapper.cs
В global.asax я вызываю Bootstrapper.Init (), и это вызывает x.AddRegistry (new ServiceRegistry ()) и т. Д.
В моих модульных тестах вам не нужно использовать DI только в ваших интеграционных тестах. В моих IntegrationTests, например, если я тестирую NHibernate через базу данных, я могу инициализировать SM с помощью RepositoryRegistry в TestSetUp с помощью вспомогательного метода, просто оборачивая GetInstance ().
Я не разделяю проекты .Bootstraper и .Domain, пока я не абсолютно необходимо ... Три проекта, X, X.UnitTests, X.Integration, если вам потребуется больше перемещений позже. У меня был опыт работы в компании, у меня были десятки проектов, которые сначала казались грязными, но не сейчас, я быстро набираю обороты и реорганизую структуру решений позже, если потребуется.
Если вы единственный, кто работает над проектом, я сначала сделаю то, что имеет для вас смысл . Нет ничего хуже, чем навязать вам структуру каталогов или проекта, которую вы считаете неинтуитивной. Находится ли класс BaseController в папке \ Core \ или в папке \ Controller \? Лично я бы посмотрел в Контроллер, но некоторые люди клянутся, что он должен быть в \ Core \ или \ Bases.
Первая ловушка для новичков думает, что вы можете организовать свой код неправильно и каким-то образом это отражается на успехе проекта. Я видел проекты, в которых 30 файлов находилось в одной папке, и другие проекты, где было 20 папок для 30 файлов.
Вторая ловушка для новичков забывает, что по сравнению с другими языками у вас есть потрясающее преимущество intellisense, инструменты навигации по коду, и поддержка рефакторинга из Visual Studio. У вас также есть компилятор, который делает размещение файла гораздо менее болезненным. Если вы положили что-то в «неправильное» место, ничего страшного, вы всегда можете найти это и перетащить туда, где это нужно.
Честно говоря, я работаю над проектом прямо сейчас и даже не уверен, где находятся определенные классы в моей файловой структуре. Перейти к определению / объявлению - это сочетания клавиш, которые я часто использую. Поскольку с кодом работаю только я, это нормально. Если бы мне пришлось добавить в проект еще одного разработчика, я бы, вероятно, все поправил.
Лично я обычно помещаю интерфейсы с их типами реализации в одну и ту же папку. IPaymentGateway находится в той же папке, что и AuthorizeNetGateway и PaypalGateway. Если я могу' t просматривать все файлы в этой папке сразу на боковой панели обозревателя решений, затем я перемещаю все файлы шлюза в папку \ Gateway \.
С добавлением Dependency Injection к смеси я бы посоветовал вам заботиться только о пространстве имен взрывы. Худшее, что вы можете сделать, - это загромождать ваши загрузчики и файлы длинными объявлениями и псевдонимами using.
ForRequestedType<Customer>
чище, чем
using KevDog.Models
using Customer=KevDog.Models.Customer
или
ForRequestedType<KevDog.Models.Customer>
. Другой способ избежать этой проблемы - явным образом указывать имена вещей: Customer , CustomerViewModel, CustomerController, CustomerDataRow, CustomerView
Для TDD вам почти необходимо иметь два загрузчика для управления конкретными типами. Вы действительно не хотите, чтобы ваши модульные тесты использовали AuthorizeNetGateway: IPaymentGateway, а скорее StubGateway: IPaymentGateway.
Теперь я ' m также новичок в DI, поэтому я стараюсь делать вещи очень простыми и копировать учебники и документацию уровня 101. Переход к динамическому внедрению на основе конфигурации сборки следует использовать только тогда, когда этого требует конкретная ситуация, и вы точно знаете, почему это делаете.
Я обычно сохраняю структуру по умолчанию для приложений MVC. Просто проще иметь код в той же структуре, что и 99% всех руководств и видео.
Надеюсь, это поможет.
Это моя первая попытка решить ту же проблему для себя, но, поскольку это моя первая попытка, я надеюсь, что люди прокомментируют или критикуют ее настолько, насколько я надеюсь, что это может служить одним из возможных решений для вас:
public VatManager()
: this(new VatManagerRegistry()) { }
public VatManager(Registry registry)
: this(new Action<IInitializationExpression>(x => { x.AddRegistry(registry); }))
{
}
public VatManager(Action<IInitializationExpression> action)
{
ObjectFactory.Initialize(action);
data = ObjectFactory.GetInstance<IVatManagerData>();
}
У меня есть три перегрузки конструктора - конструктор по умолчанию без параметров знает конкретный реестр StructureMap, который необходимо создать для использования в производственном контексте. Два других позволяют другому коду, который создает экземпляр этого класса менеджера, предоставлять свои собственные реестры StructureMap или действия, чтобы они могли сами управлять инъекциями зависимостей, например, в случае автоматизированного теста, предоставляющего имитацию вместо конкретных экземпляров тех. зависимости. Я должен добавить, что это решение не является специфическим для контекста ASP.NET MVC и не извлекает какую-либо информацию о конфигурации из файлов * .config.