Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

継続モナドその2

APIをFutureで返す。bindはとりあえず省略。

@interface Future<V> : NSObject
- (void)get:(void(^)(V))cb;
@end


@interface API<I,O> : NSObject
- (Future<O> *)getAPI:(I)input;
@end

typedef void(^CallBack)(id);
typedef void(^CPS)(CallBack);

@interface Future()
@property (nonatomic) CPS cps;
@end

@implementation Future

- (instancetype)init:(CPS)cps {
    self = [super init];
    if (self) {
        self.cps = cps;
    }
    return self;
}

- (void)get:(void (^)(id))cb {
    self.cps(cb);
    self.cps = nil;
}

@end

@implementation API
- (Future *)getAPI:(id)input {
    CPS cps = ^(CallBack cb) {
        return cb(input);
    };
    Future *future = [[Future alloc] init:cps];
    return future;
}
@end


Objective-C++でクラス

JSONを使った受け渡しを想定して書いてみた。非効率かも。

#import <Foundation/Foundation.h>

@class Engine;

typedef NSDictionary JSON;

@protocol EngineProtocol <NSObject>
- (void)engine:(nonnull Engine *)engine message:(nonnull JSON *)message;
@end

@interface Engine : NSObject
+ (nonnull instancetype)engine:(nonnull id <EngineProtocol>)delegate;
- (void)tellMessage:(nonnull JSON *)message;
@end

#include <stdio.h>
#include <iostream>

class EngineCpp;




class EngineCpp {
public:
    EngineCpp();
    ~EngineCpp();
    void hello();
    typedef std::shared_ptr<EngineCpp> Ptr;
    std::string message;
    std::string proc(std::string src);
};

EngineCpp::EngineCpp() {
    std::cout << "EngineCpp new" << std::endl;
}

EngineCpp::~EngineCpp() {
    std::cout << "EngineCpp delete" << std::endl;
}

void EngineCpp::hello() {
    std::cout << "EngineCpp hello" << std::endl;
}

std::string EngineCpp::proc(std::string src) {
    return "{\"Hello\":" + src + "}";
}

@interface NSJSONSerialization(String)
+ (NSString *)jsonString:(NSDictionary *)dic;
+ (NSDictionary *)jsonString_r:(std::string &)str;
@end

@implementation NSJSONSerialization(String)
+ (NSString *)jsonString:(NSDictionary *)dic {
    NSData *d = [NSJSONSerialization dataWithJSONObject:dic
                                                options:NSJSONWritingPrettyPrinted
                                                  error:nil];
    NSString *sd = [[NSString alloc] initWithData:d
                                         encoding:NSUTF8StringEncoding];
    return sd;
}

+ (NSDictionary *)jsonString_r:(std::string &)str {
    NSData *data = [NSData dataWithBytes:str.c_str() length:str.length()];
    
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data
                                                        options:NSJSONReadingMutableContainers                                                          error:nil];
    return dic;
}

@end




@interface Engine()
@property (nonatomic) id <EngineProtocol> delegate;
@property (nonatomic, assign) EngineCpp::Ptr engineCpp;
@end


@implementation Engine {
}

- (void)dealloc {
    NSLog(@"Engine dealloc");
}

+ (instancetype)engine:(id<EngineProtocol>)delegate {
    Engine *engine = [Engine new];
    engine.delegate = delegate;
    engine.engineCpp = std::make_shared<EngineCpp>();

    return engine;
}


- (void)tellMessage:(JSON *)message {

    std::string str = [NSJSONSerialization jsonString:message].UTF8String;
    
    std::string result = self.engineCpp->proc(str);
    
    NSDictionary *dic = [NSJSONSerialization jsonString_r:result];
    
    [self.delegate engine:self message:dic];
}

@end

一文字づつ区切る

NSStringEnumerationByComposedCharacterSequencesを用いる。

        NSString *string= @"ハローワールド🗾";
        
        NSMutableArray *list = [NSMutableArray array];
        
        [string enumerateSubstringsInRange:NSMakeRange(0,string.length)
                                                   options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
                                                       [list addObject:substring];
                                                   }];
        for (NSString *sub in list) {
            NSLog(@"%@", sub);
            for (int i=0;i<sub.length;i++) {
                NSLog(@"%04x", [sub characterAtIndex:i]);
            }
                  
        }

NSCalender

NSDateを用いた演算などができる。

NSCalendar - Foundation | Apple Developer Documentation
iOS8からの日付(NSDate)操作・比較 - Qiita


NSDateFormatter
NSDateComponent

参考になる
dev.classmethod.jp
http://www.toyship.org/archives/1665


RTC
リアルタイムクロック - Wikipedia


UTC
協定世界時 - Wikipedia


カレンダー
yuriken27.hatenablog.com
d.hatena.ne.jp

商品の値段とNSNumberFormatter

SKProductの価格の加工などで使う。

    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    formatter.formatterBehavior = NSNumberFormatterBehavior10_4;
    formatter.numberStyle = NSNumberFormatterCurrencyStyle;
    formatter.locale = locale;
    NSString *string = [formatter stringFromNumber:price];

クラスで作ってみるIF

Objective-C Advent Calendar 2014に登録していたのですが何もネタが思いつかなかったので、クラスで最小の部品を作ってみようかと思い作ってみました。

クラスIFです。
KatagiriSo/IF · GitHub


使い方は

        //ex1
        
        int a = -3;
        [[IF Condition:((a>=0) ? OK.new : nil)
                Action:[Do b:^{NSLog(@"a=>0");return OK.new;}]
                  Else:[IF Condition:((a<0) ? OK.new : nil)
                              Action:[Do b:^{NSLog(@"a<0");return OK.new;}]
                                Else:NG.new]
          ] do];

‥汚いですね。

IFクラスの引数はDoプロトコルを持ちます。

@protocol Do <NSObject>
- (id<Do>)do;
@end

クラス定義です。

typedef id<Do>(^DoBlock)(void);

@interface IF : NSObject <Do>
+ (IF*)Condition:(id<Do>)condition Action:(id<Do>)d Else:(id<Do>)e;
- (DoBlock)getDoBlock;
@property (nonatomic) id<Do>Action;
@property (nonatomic) id<Do>Condition;
@property (nonatomic) id<Do>Else;
@end

ConditionにはOKならOKクラスを入れます。

その場合にActionが実行されます。
単なるクラスなので変数に入れられます。あとBlocksにも変換できたり、返り値としてDoプロトコル
が得られたりします。

        IF *iff = [IF Condition:((a>=0) ? OK.new : nil)
                          Action:[Do b:^{NSLog(@"a=>0");return OK.new;}]
                            Else:[IF Condition:((a<0) ? OK.new : nil)
                                        Action:[Do b:^{NSLog(@"a<0");return OK.new;}]
                                          Else:NG.new]
                    ];
        DoBlock doblock = iff.getDoBlock;
        
        doblock();


何かに使えないか。。

注 Doクラス、OKクラス

@interface Do : NSObject<Do>
@property (nonatomic, copy) DoBlock doblock;
+ b:(DoBlock)doBlock;
@end
@interface OK : NSObject<Do>
@end
@implementation OK
- (id <Do>)do
{
    return OK.new;
}
@end

調査中の事々

NSSecureCoding

NSSecureCoding Protocol Reference

以下を読んだ。
Cocoaの日々: NSSecureCoding - セキュアなプロセス間通信への小さな布石


iOS6から。なぜiOS6からかというとXPCサービスの導入で非公開APIとして導入されたらしい。

Cocoaの日々: [Mac] Lion から導入された XPC Services

iOS8での外部extentionとのつながりについて調査中

Foundation Constants Reference