やりたい事
- キーチェインアクセスで証明書を作成
- メンバセンター → iOS Provisioning Portal → Certificates
- 1のファイルをアップロードしてsubmit
- できたファイルをダウンロードしてインストール
という手順。
ところが、3番がなんどやっても上手く行かない。
アップロード画面になんども戻されるし、エラーメッセージもでない…。
結論
ブラウザが悪い!(Mac + Google Chrome)
という事にw
FireFoxでやったら普通にできた…。
というわけで、ブラウザには気をつけよう!という事を再認識できた事件でしたとさ。
viewが表示された時点で、UITextViewにフォーカスを当てる為に、
viewDidLoadでbecomeFirstResponderをしてました。
どうやらこれが原因みたい…。
コメントアウトすると起きない…。
この警告が出る時は、動作が重くなる。
(UITextViewにフォーカスが当たってキーボードが立ち上がるまでに一瞬間がある)
標準アプリも似たような動きをしてる気がするんだよな…。
もしかして、iOSのバグ?
要追加調査。
今更ながらHyperEstraierいじってました。
うちのサービスに導入予定。3万件くらいのデータを検索させる。
やっぱり、WHERE句にLIKE付けるよりいいよね!
HyperEstraierのインデックス作成とか検索部分とかをPHPのライブラリとして公開したいなぁ。
前職で作ってた奴を思い出して。
完成したらこのブログに載せよう!
Rubyだとstrip、PHPだとtrim
API側で削れ!!でもいいんだけど…。
Objective-Cではどうやるのか調べた
stringByTrimmingCharactersInSet
というメソッドでできる。
[str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
とやると、空白&改行を削ってくれる。
って、メソッド名長いでしょ…。
面倒だからNSStringを拡張
#import <Foundation/Foundation.h> @interface NSString(TrimMethods) - (NSString *)trim; - (NSString *)strip; @end
#import "NSStringExtensions.h"
@implementation NSString(TrimMethods)
- (NSString *)trim
{
return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (NSString *)strip
{
return [self trim];
}
@end
短くなった!
[str trim]; [str strip];
で使えるよ!
地点Aから見た地点Bの方位を求めたかったので、
色々調べて実装してみた。
CLLocationを拡張。
参考は、こちら
CLLocationExtensions.h
#import <Foundation/Foundation.h> #import <CoreLocation/CoreLocation.h> #import <math.h> @interface CLLocation(Extensions) - (CLLocationDirection)azimuthToLocation:(const CLLocation *)target; @end
CLLocationExtensions.m
#import "CLLocationExtensions.h"
#define kEquatorialRadius 6378137 // 赤道半径
@implementation CLLocation(Extensions)
- (CLLocationDirection)azimuthToLocation:(const CLLocation *)target
{
CLLocationDirection dx = kEquatorialRadius * (target.coordinate.latitude - self.coordinate.latitude) * cos(self.coordinate.longitude);
CLLocationDirection dy = kEquatorialRadius * (target.coordinate.longitude - self.coordinate.longitude);
return atan2(dy, dx);
}
@end
使い方
CLLocation *own = [[CLLocation alloc] initWithLatitude:緯度 longitude:経度];
CLLocation *target = [[CLLocation alloc] initWithLatitude:緯度 longitude:経度];
NSLog("[own => target] %f°", [own azimuthToLocation:target]);
みたいに使えます。
ちょっとPHPから叩きたかったのでクライアントを作ってみた。
http://github.com/taka0125/Instapaper-API-Client-For-PHP5
2つしかAPIないからライブラリにしなくてもいいんだけど…。
独自クラス作るより使い回しが楽そうなので、メモ。
CLLocationExtensions.h
#import <Foundation/Foundation.h> #import <CoreLocation/CoreLocation.h> @interface CLLocation (Extensions) - (CLLocationDegrees)latitude; - (CLLocationDegrees)longitude; - (BOOL)isBetterAccuracyThan:(CLLocation *)location; - (BOOL)isBetterHorizontalAccuracyThan:(CLLocation *)location; - (BOOL)isBetterVerticalAccuracyThan:(CLLocation *)location; - (NSString *)description; @end
CLLocationExtensions.m
#import "CLLocationExtensions.h"
@implementation CLLocation (Extensions)
- (CLLocationDegrees)latitude
{
return self.coordinate.latitude;
}
- (CLLocationDegrees)longitude
{
return self.coordinate.longitude;
}
- (BOOL)isBetterAccuracyThan:(CLLocation *)location
{
if (![self isBetterHorizontalAccuracyThan:location]) return NO;
if (![self isBetterVerticalAccuracyThan:location]) return NO;
return YES;
}
- (BOOL)isBetterHorizontalAccuracyThan:(CLLocation *)location
{
if (signbit(location.horizontalAccuracy)) return NO;
if (self.horizontalAccuracy <= location.horizontalAccuracy) return YES;
return NO;
}
- (BOOL)isBetterVerticalAccuracyThan:(CLLocation *)location
{
if (signbit(location.verticalAccuracy)) return NO;
if (self.verticalAccuracy <= location.verticalAccuracy) return YES;
return NO;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"緯度 = %f\n経度 = %f\n高度 = %f\n精度(水平) = %f\n精度(垂直) = %f", [self latitude], [self longitude], self.altitude, self.horizontalAccuracy, self.verticalAccuracy];
}
@end
GPSを使って位置情報を取得するサンプル。
まずは、GPSのデータ
ひとまず使いそうなものだけをピックアップしたクラス
GPSData.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
@interface GPSData : NSObject
{
CLLocationDegrees latitude_; // 緯度
CLLocationDegrees longitude_; // 経度
CLLocationDistance altitude_; // 高度
CLLocationAccuracy accuracy_; // 正確さ
}
- (id)initWithLatitude:(CLLocationDegrees) latitude
longitude:(CLLocationDegrees) longitude
altitude:(CLLocationDistance) altitude
accuracy:(CLLocationAccuracy) accuracy;
- (float)latitude;
- (void)setLatitude:(CLLocationDegrees)value;
- (float)longitude;
- (void)setLongitude:(CLLocationDegrees)value;
- (float)altitude;
- (void)setAltitude:(CLLocationDistance)value;
- (float)accuracy;
- (void)setAccuracy:(CLLocationAccuracy)value;
@end
GPSData.m
#import "GPSData.h"
@implementation GPSData
- (float)latitude
{
return (float)latitude_;
}
- (void)setLatitude:(CLLocationDegrees)value
{
latitude_ = value;
}
- (float)longitude
{
return (float)longitude_;
}
- (void)setLongitude:(CLLocationDegrees)value
{
longitude_ = value;
}
- (float)altitude
{
return (float)altitude_;
}
- (void)setAltitude:(CLLocationDistance)value
{
altitude_ = value;
}
- (float)accuracy
{
return (float)accuracy_;
}
- (void)setAccuracy:(CLLocationAccuracy)value
{
accuracy_ = value;
}
- (id)init
{
if (![super init]) return nil;
latitude_ = 0.0f;
longitude_ = 0.0f;
accuracy_ = 0.0f;
return self;
}
- (id)initWithLatitude:(CLLocationDegrees) latitude
longitude:(CLLocationDegrees) longitude
altitude:(CLLocationDistance) altitude
accuracy:(CLLocationAccuracy) accuracy
{
if (![self init]) return nil;
latitude_ = latitude;
longitude_ = longitude;
altitude_ = altitude;
accuracy_ = accuracy;
return self;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"latitude = %f\nlongitude = %f\naltitude = %f\naccuracy = %f", latitude_, longitude_, altitude_, accuracy_];
}
@end
LocationTracker.h
これはシングルトン。
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import "GPSData.h"
@protocol LocationTrackerDelegate
- (void)locationUpdated:(GPSData *)data;
@end
@interface LocationTracker : NSObject <CLLocationManagerDelegate>
{
CLLocationManager *locationManager_;
GPSData *data_;
BOOL isTracking_;
id<LocationTrackerDelegate> observer_;
}
- (GPSData *)current;
- (BOOL)toggleTracking;
- (BOOL)startTracking;
- (BOOL)stopTracking;
- (void)setObserver:(id<LocationTrackerDelegate>)observer;
+ (id)instance;
@end
@interface LocationTracker (privateMethods)
- (BOOL)allowedTracking;
@end
LocationTracker.m
#import "LocationTracker.h"
@implementation LocationTracker
static id _instance = nil;
- (GPSData *)current
{
return data_;
}
- (BOOL)toggleTracking
{
if (isTracking_) return [self stopTracking];
return [self startTracking];
}
- (BOOL)startTracking
{
if (![self allowedTracking]) return NO;
isTracking_ = YES;
[locationManager_ startUpdatingLocation];
return YES;
}
- (BOOL)stopTracking
{
isTracking_ = NO;
[locationManager_ startUpdatingLocation];
return YES;
}
- (id)init
{
if (![super init]) return nil;
locationManager_ = [[CLLocationManager alloc] init];
locationManager_.delegate = self;
isTracking_ = NO;
data_ = [[GPSData alloc] init];
observer_ = nil;
return self;
}
- (void)setObserver:(id<LocationTrackerDelegate>)observer
{
observer_ = observer;
}
- (void)dealloc
{
[locationManager_ release];
[super dealloc];
}
+ (id)instance
{
@synchronized(self) {
if (!_instance) {
[[self alloc] init];
}
}
return _instance;
}
+ (id)allocWithZone:(NSZone *)zone
{
@synchronized(self) {
if (!_instance) {
_instance = [super allocWithZone:zone];
return _instance;
}
}
return nil;
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)returnCount
{
return UINT_MAX;
}
- (void)release
{
}
- (id)autorelease
{
return self;
}
@end
@implementation LocationTracker (privateMethods)
- (BOOL)allowedTracking
{
return [CLLocationManager locationServicesEnabled];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[data_ initWithLatitude:newLocation.coordinate.latitude
longitude:newLocation.coordinate.longitude
altitude:newLocation.altitude
accuracy:newLocation.horizontalAccuracy];
if (observer_) {
[observer_ locationUpdated:data_];
}
}
@end
使い方
- (void)start
{
[[LocationTracker instance] setObserver:self];
[[LocationTracker instance] startTracking];
}
- (void)stop
{
[[LocationTracker instance] stopTracking];
}
- (void)locationUpdated:(GPSData *)data
{
// 位置が変わった時に呼ばれる
}
RubyみたいにDate.todayとかが使いたかったので拡張してみた。
NSDateExtension.h
#import <Foundation/Foundation.h> @interface NSDate(exDateMethods) + (NSDate *)now; + (NSDate *)today; - (NSDate *)daysAgo:(unsigned int)days; - (NSDate *)daysAfter:(unsigned int)days; - (NSDate *)hoursAgo:(unsigned int)hours; - (NSDate *)hoursAfter:(unsigned int)hours; - (NSDate *)next; - (NSDate *)prev; - (NSString *)format:(NSString *)format; - (NSString *)strftime:(NSString *)format; - (BOOL)laterThan:(NSDate *)date; @end
NSDateExtension.m
#import "NSDateExtension.h"
@implementation NSDate(exDateMethods)
+ (NSDate *)now
{
return [NSDate date];
}
+ (NSDate *)today
{
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setTimeStyle : NSDateFormatterNoStyle];
[formatter setDateStyle : NSDateFormatterMediumStyle];
NSString *todayString = [formatter stringFromDate:[NSDate date]];
return [formatter dateFromString:todayString];
}
- (NSDate *)daysAgo:(unsigned int)days
{
return [self initWithTimeInterval:-1.0 * days * 24 * 60 * 60 sinceDate:self];
}
- (NSDate *)daysAfter:(unsigned int)days
{
return [self initWithTimeInterval:days * 24 * 60 * 60 sinceDate:self];
}
- (NSDate *)hoursAgo:(unsigned int)hours
{
return [self initWithTimeInterval:-1.0 * hours * 60 * 60 sinceDate:self];
}
- (NSDate *)hoursAfter:(unsigned int)hours
{
return [self initWithTimeInterval:hours * 60 * 60 sinceDate:self];
}
- (NSDate *)next
{
return [self daysAfter:1];
}
- (NSDate *)prev
{
return [self daysAgo:1];
}
- (NSString *)format:(NSString *)format
{
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:format];
return [formatter stringFromDate:self];
}
- (NSString *)strftime:(NSString *)format
{
return [self format:format];
}
- (BOOL)laterThan:(NSDate *)date
{
if ([self timeIntervalSinceDate:date] < 0) return YES;
return NO;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "NSDateExtension.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSDate *today = [NSDate today];
NSDate *yesterday = [today prev];
NSDate *now = [NSDate now];
NSLog(@"%@", today);
NSLog(@"%@", [today next]);
NSLog(@"%@", [today prev]);
NSLog(@"%@", now);
NSLog(@"%@", [now next]);
NSLog(@"%@", [now prev]);
NSLog(@"%@", [now strftime:@"hh:mm:ss"]);
NSLog(@"%@", [now format:@"hh:mm:ss"]);
NSLog(@"%d", [now laterThan:yesterday]);
[pool drain];
return 0;
}
一応、RubyでもSingleton。
Rubyは標準で実装されているから楽。
test.rb
require 'singleton' class SingletonTest include Singleton end p SingletonTest.instance p SingletonTest.instance
サンプル実行
$ ruby test.rb #<SingletonTest:0xb7d579a8> #<SingletonTest:0xb7d579a8>

最新コメント