SBJSONを使う。
■実装
まず、以下のようにインポートする。
#import "JSON.h"
次に以下のように使用する。
SBJSON *parser = [[SBJSON alloc] init]; NSDictionary *json = [parser objectWithString:str error:nil];
簡単。(●´ω`●)
SBJSONを使う。
まず、以下のようにインポートする。
#import "JSON.h"
次に以下のように使用する。
SBJSON *parser = [[SBJSON alloc] init]; NSDictionary *json = [parser objectWithString:str error:nil];
簡単。(●´ω`●)
以下の記述によって透明度を設定することができる。
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; btn.alpha = 0.80;
以下の記述によってタッチを無効化することができる。
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; btn.userInteractionEnabled = NO;
0からOAuthのクライアントコードを書くのは面倒なので、oauthconsumerを使用する。
実はライブラリのページには以下のような質問が掲載されているが返答がされていないようだ。
Hello, I am trying to submit some JSON data to a web service using a POST request. For some reason however, the framework seems to look for additional parameters in the HTTP body where I put my JSON data. This results in an index-out-of-range exception since it is unable to split the HTTP body into parameter components.
以下のように実装すると、application/jsonでPOSTすることができる。
NSURL *url = [NSURL URLWithString:@"https://example.com/user/1/flights/"]; OAConsumer *consumer = [[OAConsumer alloc] initWithKey:@"mykey" secret:@"mysecret"]; OAToken *accessToken = [[OAToken alloc] initWithKeychainUsingAppName:@"MyApp" serviceProviderName:@"Example.com"]; OAMutableURLRequest *req = [[OAMutableURLRequest alloc] initWithURL:url consumer:consumer token:accessToken realm:nil signatureProvider:nil]; [req setHTTPMethod:@"POST"]; [req prepare]; [req setHTTPBody:[(NSString*)jsonStr dataUsingEncoding:NSUTF8StringEncoding]]; [req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; OADataFetcher *fetcher = [[OADataFetcher alloc] init]; [fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(apiTicket:didFinishWithData:) didFailSelector:@selector(apiTicket:didFailWithError:)];
ちなみに通常のPOSTをしたい場合は、ドキュメントにもあるように以下のようにする。
NSURL *url = [NSURL URLWithString:@"https://example.com/user/1/flights/"]; OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url consumer:consumer token:accessToken realm:nil signatureProvider:[[OAPlaintextSignatureProvider alloc] init]]; OARequestParameter *nameParam = [[OARequestParameter alloc] initWithName:@"title" value:@"My Page"]; OARequestParameter *descParam = [[OARequestParameter alloc] initWithName:@"description" value:@"My Page Holds Text"]; NSArray *params = [NSArray arrayWithObjects:nameParam, descParam, nil]; [request setParameters:params]; OADataFetcher *fetcher = [[OADataFetcher alloc] init]; [fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(apiTicket:didFinishWithData:) didFailSelector:@selector(apiTicket:didFailWithError:)];
ちなみにPHPで同じことをする場合は以下のように記述する。
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://justoneplanet.info'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, '{"hogehoge" : "fugafuga"}'); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($ch, CURLOPT_HEADER, TRUE); $result = curl_exec($ch);
<?php if($this->Session->check('Message.auth')){ echo $this->Session->flash();// error msg echo $this->Session->flash('auth');// error msg } echo $form->create( 'Admin', array( 'url' => array( 'controller' => 'users', 'action' => 'login' ) ) ); ?> <div data-role="fieldcontain"> <dl> <dt><label for="name">ユーザ名</label></dt> <dd><?php echo $form->input( 'name', array( 'div' => false, 'label' => false, 'id' => 'name' ) ); ?></dd> </dl> </div> <div data-role="fieldcontain"> <dl> <dt><label for="password">パスワード</label></dt> <dd><?php echo $form->input( 'password', array( 'div' => false, 'label' => false, 'id' => 'password', 'value' => '' ) ); ?></dd> </dl> <p><?php echo $form->submit( 'ログイン', array( 'div' => false, 'label' => false, ) ); ?></p> <?php echo $form->end(); ?>
QuartzCoreをインポートする。
#import <QuartzCore/QuartzCore.h>
以下のように記述する。
[textview.layer setCornerRadius:8.0f];
めも。
UIImage *bg = [[UIImage imageNamed:@"button.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:10]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [btn setFrame:CGRectMake(20, 366, 136, 38)]; [btn setBackgroundImage:btnBg forState:UIControlStateNormal];
UNIXベースなので以下のコマンドでインストールしてみる。
/Applications/XAMPP/xamppfiles/bin/pear upgrade pear channel-update pear.php.net /Applications/XAMPP/xamppfiles/bin/pear upgrade pear upgrade PEAR /Applications/XAMPP/xamppfiles/bin/pecl install xdebug
コンパイルで大量のエラーが出て上手くいかないはずだ。
Komodo Remote Debugging Package Downloadsで、「Downloads > PHP Remote Debugging Client > Mac OS X (universal)」をクリックしてダウンロードし、PHPのバージョンに合ったファイルを以下のコマンドでコピーする。
cp /Users/[user]/Downloads/Komodo-PHPRemoteDebugging-6.1.0-60797-macosx/5.x/xdebug.so /Applications/XAMPP/xamppfiles/lib/php/php-5.x.x/extensions/no-debug-non-zts-20xxxxxx/xdebug.so
以下のコマンドを実行する。
vi /Applications/XAMPP/xamppfiles/etc/php.ini
次に、以下の一行を加える。
[xdebug] zend_extension ="/Application/XAMPP/xamppfiles/lib/php/php-5.x.x/extensions/no-debug-non-zts-20xxxxxx/xdebug.so" xdebug.remote_enable = 1 xdebug.remote_host = 127.0.0.1 xdebug.remote_port = 9000 xdebug.remote_handler = dbgp xdebug.profiler_enable = 1 xdebug.profiler_output_dir = "/Applications/XAMPP/xamppfiles/htdocs/_xdebug_profiler" xdebug.profiler_output_name = cachegrind.out.%s
ついでにマルチバイト系の設定をし忘れてたのでやっておく。
mbstring.language = Japanese mbstring.internal_encoding = UTF-8 mbstring.http_output = UTF-8 expose_php = Off
500個めの記事でしたーσ°▽°)σ
history
以上。
ネストした型はエンクロージング型にアクセスできる場合にだけアクセスできる。また、アクセスの観点などから1レベルだけのネストが推奨される。
public class BankAccount { private long number; private long balance; public static class Permissions { public boolean canDeposit, canWithdraw, canClose; } }
ネストしたインターフェースは常にstaticであるが慣習的に省略される。
staticでないクラスメンバーはそのクラスのインスタンスと関連付けされている。内部クラスのオブジェクトは常にエンクロージングインスタンスと関連付けされている。
public class BankAccount { private long number; private long balance; private Action lastAction; public class Action { private String action; private long amount; Action(String action, long amount) { this.action = action; this.amount = amount; } public String toString() { return number + ": " + action + " " + amount; } } public void deposit(long amount) { balance += amount; lastAction = new Action("deposit", amount); } public void withdraw(long amount) { balance -= amount; lastAction = new Action("withdraw", amount); } }
通常、内部クラスのオブジェクトはdepositやwithdrawの中で行われたようにエンクロージングクラスのインスタンスメソッドの内部で生成される。
lastAction = new Action("deposit", amount);
上述のコードを厳密に書くと以下のようになる。
lastAction = this.new Action("deposit", amount);
staticフィールドを持つことができないのでstatic finalにするかインスタンスフィールドにする必要がある。
以下のようにエンクロージングクラスは明示的な参照を通して、内部クラスのprivateメンバにアクセスできる。
public void deposit(long amount) { balance += amount; lastAction = new Action("deposit", amount); String str = lastAction.action; }
以下のように内部クラスからエンクロージングクラスにアクセスすることができる。
public String toString() { return number + ": " + action + " " + amount; }
また以下のように限定的なthisを用いて記述することもできる。
public String toString() { return BankAccount.this.number + ": " + action + " " + amount; }
但し、staticメソッドなどから限定的なthisを用いることはできない。
以下のようなクラスを考える。
class Outer { class Inner {} }
以下のようにして拡張することができる。
class ExOuter extends Outer { class ExInner extends Inner {} }
内部サブクラスのエンクロージングクラスがOuterのサブクラスでない場合、内部サブクラス自身が内部クラスでない場合、superを通してInnerのコンストラクタを呼び出す際にOuterオブジェクトへの明示的な参照を提供しなくてはならない。
class Unrelated extends Outer.Inner { Unrelated(Outer ref) { ref.super(); } }
以下のように同名のメソッドを内部クラスで定義すると、引数に関係なくエンクロージングクラスのメソッドが隠蔽される。
class Outer { void print() {} void print(int val) {} class Inner { void print() {}// エンクロージングクラスの全てのprintメソッドを隠蔽する void show() { print(1);// コンパイルエラー } } }
以下のようにメソッド本体(コンストラクタや初期化ブロックなど)のコードブロックの中で内部クラスを定義することができる。
public void onClick(View v) { class BankAccount {} BankAccount bankAccount = new BankAccount(); }
コードブロックの外からはアクセスできず完全にローカルである。また、staticとする事はできない。
以下のようにして無名内部クラスを定義することができる。無名内部クラスはコンストラクタを持つことができない。
private static Iterator<Object> walk(final Object[] objs) { return new Iterator<Object>() { private int position = 0; @Override public boolean hasNext() { return (position < objs.length); } @Override public Object next() { if (position >= objs.length) { throw new NoSuchElementException(); } return objs[position++]; } @Override public void remove() { throw new UnsupportedOperationException(); } }; }
明示的なコンストラクタを必要とする場合はローカル内部クラスを使用するべきである。また、6行を超えるような無名内部クラスは可読性の観点から避けるべきである。
以下のようなコードを考える。
abstract class Device { abstract class Port { } }
class Printer extends Device { class SerialPort extends Port { } Port serial = new SerialPort(); }
class HighSpeedPrinter extends Printer { class SerialPort extends Printer.SerialPort { } // 継承されたメンバserialは親クラスのSerialPortのインスタンスである }
一方で以下のようにファクトリーメソッドを用いてオブジェクトを生成する場合を考える。
class Printer extends Device { class SerialPort extends Port { } Port serial = createSerialPort(); protected Port createSerialPort() { return new SerialPort(); } }
class HighSpeedPrinter extends Printer { class EnhancedSerialPort extends SerialPort { } // 継承されたメンバserialは初期化の際にカレントクラスでOverrideされたcreateSerialPortが呼ばれる protected Port createSerialPort() { return new EnhancedSerialPort(); } }
以下のようにしてインターフェース内でネストしたクラスを定義することができる。
interface Changeable { class Record { public Object changer; public String changeDesc; } Record getLastChange(); }
暗黙的にpublicかつstaticになる。
以下のようにすることでSharedDataを利用しているコードは、data参照を通して共通の状態を共有できる。
interface SharedData { class Data {// 暗黙的にstatic private int x = 0; public int getX() {return x;} public void setX(int x){this.x = x;} } Data data = new Data(); }
JavaやPHPのインターフェース的なもの。
動物という種は存在しないので、以下のようにプロトコルとして定義した。
#import <Foundation/Foundation.h> @protocol Animal @property(copy, readwrite) NSString *_name; -(id) init:(NSString *)name;// initialize -(NSString *) cry: (NSString *)name;// instance method +(NSString *) getKind; // class method @end
上述で定義したプロトコルを以下のようにして実装する。
#import "Animal.h" @interface Dog:NSObject<Animal> @end
以下のように実装する。
#import "Dog.h" @implementation Dog @synthesize _name; - (id) init: (id) name { self._name = name; return self; } -(NSString *)cry: (NSString *)name{ return [NSString stringWithFormat:@"bow! from %@ to %@", self._name, name]; } +(NSString *)getKind{ return @"Dog"; } @end
ちなみに、プロトコルで宣言したメソッドが実装されていない場合、warningが発生する。
複数のクラスに分割したり、クラスに新しい機能を追加したりできる。
#import <Foundation/Foundation.h> @interface NSString(Trim) - (NSString *) trim; @end
#import "trim.h" @implementation NSString(Trim) - (NSString *) trim{ return [self stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; } @end
上述の記述によって、NSStringクラスにTrimメソッドが追加される。文法は全然違うけどJSのprototype的な発想かもしれん。