GPSのサンプル

On 2010年9月30日, in Objective-C, by タカ

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
{
    // 位置が変わった時に呼ばれる
}
Tagged with:  

NSDateの拡張

On 2010年9月15日, in Objective-C, by タカ

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;
}
Tagged with:  

Objective-Cでsha1

On 2010年9月14日, in Objective-C, by タカ

http://d.hatena.ne.jp/WaterFlea/20091011/1255242225
を参考にさせてもらい、NSStringを拡張して、実装。


Crypto.h

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>

@interface NSData(exDigest)
+ (NSData *)utf8Data: (NSString *)string;
- (NSData *)sha1Digest;
- (NSData *)md5Digest;
- (NSString *)hexString;
- (NSString *)sha1String;
@end

@interface NSString(exDigest)
- (NSString *)sha1String;
@end

Crypto.m

#import "Crypto.h"

@implementation NSData(exDigest)

+ (NSData *)utf8Data:(NSString *) string
{
    const char* utf8str = [string UTF8String];
    NSData* data = [NSData dataWithBytes: utf8str length: strlen(utf8str)];
    return data;
}

- (NSData *)sha1Digest
{
    unsigned char result[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1([self bytes], [self length], result);
    return [NSData dataWithBytes:result length:CC_SHA1_DIGEST_LENGTH];
}

- (NSData *)md5Digest
{
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5([self bytes], [self length], result);
    return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH];
}

- (NSString *)sha1String
{
    return [[self sha1Digest] hexString];
}

- (NSString *)hexString
{
    unsigned int i;
    static const char *hexstr[16] = { "0", "1", "2", "3",
        "4", "5", "6", "7",
        "8", "9", "a", "b",
        "c", "d", "e", "f" };
    const char *dataBuffer = (char *)[self bytes];
    NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:([self length] * 2)];
    for (i=0; i<[self length]; i++) {
        uint8_t t1, t2;
        t1 = (0x00f0 & (dataBuffer[i])) >> 4;
        t2 =  0x000f & (dataBuffer[i]);
        [stringBuffer appendFormat:@"%s", hexstr[t1]];
        [stringBuffer appendFormat:@"%s", hexstr[t2]];
    }

    return [[stringBuffer copy] autorelease];
}
@end

@implementation NSString(exDigest)
- (NSString *)sha1String
{
    return [[NSData utf8Data: self] sha1String];
}
@end

main.m

#import <Foundation/Foundation.h>
#import "Crypto.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSLog(@"%@", [[NSData utf8Data: @"test"] sha1String]);
    NSLog(@"%@", [@"test" sha1String]);
    [pool drain];
    return 0;
}
Tagged with:  

Singleton

On 2010年9月14日, in Objective-C, by タカ

比較的よく使うのでメモとしてエントリー


Singleton.h

#import <Foundation/Foundation.h>
@interface Singleton : NSObject {

}
+ (id)instance;

Singleton.m

@implementation Singleton

static id _instance = nil;

+ (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

Objective-Cでsha1

On 2010年4月10日, in Objective-C, by タカ

ヘッダファイルは、Encrypt.hというファイル名で

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>

@interface NSData(exDigest)
+ (NSData *) utf8Data: (NSString *) string;
- (NSData *) sha1Digest;
- (NSData *) md5Digest;
- (NSString *) hexString;
- (NSString *) sha1String;
@end

mファイルは、Encrypt.mというファイル名で

#import "Encrypt.h"
@implementation NSData(exDigest)
+ (NSData *) utf8Data: (NSString *) string
{
    const char* utf8str = [string UTF8String];
    NSData* data = [NSData dataWithBytes: utf8str length: strlen(utf8str)];
    return data;
}

- (NSData *) sha1Digest
{
    unsigned char result[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1([self bytes], [self length], result);
    return [NSData dataWithBytes:result length:CC_SHA1_DIGEST_LENGTH];
}

- (NSData *) md5Digest
{
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5([self bytes], [self length], result);
    return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH];
}

- (NSString *) sha1String
{
    return [[self sha1Digest] hexString];
}

- (NSString *)hexString
{
    unsigned int i;
    static const char *hexstr[16] = { "0", "1", "2", "3",
        "4", "5", "6", "7",
        "8", "9", "a", "b",
        "c", "d", "e", "f" };
    const char *dataBuffer = (char *)[self bytes];
    NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:([self length] * 2)];
    for (i=0; i<[self length]; i++) {
        uint8_t t1, t2;
        t1 = (0x00f0 & (dataBuffer[i])) >> 4;
        t2 =  0x000f & (dataBuffer[i]);
        [stringBuffer appendFormat:@"%s", hexstr[t1]];
        [stringBuffer appendFormat:@"%s", hexstr[t2]];
    }

    return [[stringBuffer copy] autorelease];
}
@end

実行用ファイルはmain.mとかってしてあげて

#import "Encrypt.h"

int main(void)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    NSString* str = @"test";
    NSLog(@"%@", [[NSData utf8Data: str] sha1String]);
    [pool release];
    return 0;
}

コンパイル

$ gcc -c main.m -o main.o
$ gcc -c Encrypt.m -o Encrypt.o
$ gcc -o main main.o Encrypt.o -framework Foundation

そして、実行してみる。

$ ./main
2010-04-10 15:18:51.372 main[1712:903] a94a8fe5ccb19ba61c4c0873d391e987982fbbd3

といった感じで、sha1成功。

Tagged with:  

iPhoneアプリ開発

On 2010年4月5日, in iPhone, by タカ

Macにも慣れてきたので、少しやってみました。

Objective-Cの書き方がいまいちしっくりこないけど、それなりにちまちま作ってます。

ページ遷移や、データ保持、内蔵ブラウザ

とかは、それっぽく動くようになりました。

あとは、サーバ側のAPIを作らないと進めなくなったので一時中断w

Tagged with: