Upgrade to Pro — share decks privately, control downloads, hide ads and more …

いかにしてユーザーを手玉に取るか

 いかにしてユーザーを手玉に取るか

「いかにしてユーザーを手玉に取るか」
ユーザーの行動の三手先を読んで実装するためには…みたいな UI のお話。

2013/2/23 at GREE
"conferenceWithDevelopers"

http://conference-with-developers.info/

Yusuke SUGAMIYA

February 23, 2013
Tweet

More Decks by Yusuke SUGAMIYA

Other Decks in Programming

Transcript

  1. ෆ҆ΛἤΒͳ͍Α͏ʹ͢Δɻ w ૢ࡞ʹର͢ΔϑΟʔυόοΫ͕ແ͍ɻ w ௨৴ͯ͠Δͷ͔Կ΋ͯ͠ͳ͍ͷ͔۠ผग़དྷͳ͍ɻ w ཪͰ஋͕উखʹมΘͬͯΔͬΆ͍ڍಈ͕දͰݟ͑Δɻ w Ұॠදࣔ͞ΕͯɺԿ΋ݴΘͣʹඇදࣔʹͳΔɻ w

    Ϙλϯ͕͋Δͷʹԡͤͳ͍ɻ w ಺༰͕Α͘෼͔Βͳ͍ΤϥʔΞϥʔτ͕ग़Δɻ ࣮૷ͯ͠Δؒ͸೉͍͠ɻ ࡞ͬͨਓؒ͸ʮ͜͏͢Ε͹͜͏ͳΔʯͬͯطʹ෼͔ͬͯΔ͔Βɻ
  2. UIView @property(nonatomic, getter=isUserInteractionEnabled) BOOL userInteractionEnabled; UIControl @property(nonatomic, getter=isEnabled) BOOL enabled;

    - (void)cancelTrackingWithEvent:(UIEvent *)event; UIGestureRecognizer @property(nonatomic, getter=isEnabled) BOOL enabled; UIScrollViewDelegate UIGestureRecognizerDelegate
  3. - (BOOL)gestureRecognizer: (UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch { // iOS 6 Ͱ͸ඞཁͳ͍… if

    (touch.view != gestureRecognizer.view && [touch.view isKindOfClass:[UIControl class]]) { return NO; } // ޙ͸ී௨ʹॻ͘…
  4. // Ϣʔβͷࢦ͕σόΠεը໘ͱ઀৮͍ͯ͠Δ৔߹ɺYES @property(nonatomic, readonly, getter=isTracking) BOOL tracking; // Ϣʔβͷࢦ͕σόΠεը໘ͱ઀৮͍ͯͯ͠ಈ͍ͨ৔߹ɺYES @property(nonatomic,

    readonly, getter=isDragging) BOOL dragging; // ϑϦοΫδΣενϟɺ·ͨ͸Scroll ViewͷϑϨʔϜΛ௒͑ͯυϥοάͯ͠ // ό΢ϯεͨ݁͠ՌɺscrollView ͕ݮ଎͍ͯ͠Δ৔߹ɺYES @property(nonatomic, readonly, getter=isDecelerating) BOOL decelerating; // zoomScaleϓϩύςΟΛมߋ͢ΔͨΊʹ scrollView ͕ // ϐϯνδΣενϟΛ௥੻͍ͯ͠Δ৔߹ɺYES @property(nonatomic, readonly, getter=isZooming) BOOL zooming; // UIScrollViewDecelerationRateNormal ͔ UIScrollViewDecelerationFast Λ // ࢦఆ͢Δ͜ͱ͕ଟ͍ͱࢥ͏͚Ͳɺޙऀ͸ UIWebView ͬΆ͍ΞϨͰ͢ɻ @property(nonatomic) float decelerationRate;
  5. Ϣʔβʔ͕ը໘ʹλον͢Δ ↓ ͙͢ʹ tracking ͕ YES ʹͳΔ ↓ ࢦΛಈ͔͢ͱ scrollView

    ͸ਐߦதͷଞͷλονॲཧ͕͋Ε͹ͦΕΒͷΩϟϯηϧΛࢼΈͯɺdragging ͕ YES ʹͳΓ scrollViewWillBeginDragging: ͕ݺ͹ΕΔɻ ↓ scroll த͸ scrollViewDidScroll: ͕ஞ࣍ݺ͹ΕΔɻ ࢦͰಈ͔ͯ͠Δ͔Ͳ͏͔͸ؔ܎ͳ͘ɺಈ͚͹ݺ͹ΕΔɻ ࢦʹΑΔεΫϩʔϧ͔Ͳ͏͔ͷ൑ผ͸લड़ͷ tracking ͱ͔ dragging ΛݟΔඞཁ͕͋Δ͠ɺٯʹݴ ͑͹ͦΕΒ͕ NO Ͱ΋ݺ͹ΕΔɻ ࿈ଓͯ͠ݺ͹ΕΔ͚Ͳɺස౓͸ෛՙঢ়گ࣍ୈͳͷͰɺεΫϩʔϧͷ૬ର஋ΛऔΔͷ͸ࣄނͷݩͩ͠ɺݺ͹Ε ͨΒඞͣॲཧΛ͢ΔɺΈ͍ͨͳײ͡ʹॻ͔ͳ͍ͱόάͷݩʹͳΔͶɻ ↓ ࢦΛ཭͢ͱ tracking ͸ NO ʹͳΔ͠ dragging ΋ NO ʹͳͬͯ scrollViewDidEndDragging:willDecelerate: ͕ݺ͹ΕΔɻ iOS 5 Ҏ߱͸ͦͷલʹ scrollViewWillEndDragging:withVelocity:targetContentOffset: ͕ݺ͹ΕΔΜ͚ͩͲɺ๻͸ಛʹ࢖ͬͯͳ͍ɻ decelerate ͕ NO ͳΒ͜͜Ͱγʔέϯε͸͜͜ͰऴΘΓ͚ͩͲ YES ͳΒ·ͩଓ͘ → ऴྃॲཧΛ෼཭ ͯ͠ॻ͍ͱ͍ͯݺͼग़͢ܗʹ͓͔ͯ͠ͳ͍ͱ٧Ή ↓ decelerate ͕ YES ͩͬͨ৔߹ɺେମͷ৔߹͸ pagingEnabled ͕ YES ͰϑϦοΫͨ࣌͠ͱ͔ɺൣ ғ͔Β͸Έग़ͯ͠ bounce ͯ͠Δ͚࣌ͩΕͲɺ scrollViewWillBeginDecelerating: ͕ݺ͹ΕΔ ↓ ಈ͍ͯΔ͔Β scrollViewDidScroll: ͕ஞ࣍ݺ͹ΕΔɻ ↓ scrollViewDidEndDecelerating: ͕ݺ͹ΕͯγʔέϯεऴΘΓɻ
  6. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gr shouldReceiveTouch:(UITouch *)touch { BRDLOG(@"%@", NSStringFromClass([gr class])); //

    ΄ͱ͹͠ΔΞϨͳײ͡… if ([NSStringFromClass([gr class]) hasPrefix:@"UIScrollView"]) { return YES; } // ޙ͸ී௨ʹ࣮૷…
  7. ͍͖ͳΓͰ͕͢ɺ։ൃํ๏ɻ w 9DPEFʹ%FCVH 3FMFBTF 5FTU'MJHIUͭͷϏϧυઃ ఆΛ༻ҙɻαʔόʔͷ)PTU EFW TUBHF ͳͲΛมߋɻ w

    HJU 4PVSDF5SFF  HJUIVC HJUIVCJTTVFT w NBTUFSϒϥϯνͷΈɻ w ཤྺ͑͞ݟ͑Ε͹͍͍ͷͰಛʹ෼͚ͳ͍ɻ
  8. ͍͖ͳΓͰ͕͢ɺ։ൃํ๏ɻ w 9DPEFʹ%FCVH 3FMFBTF 5FTU'MJHIUͭͷϏϧυઃ ఆΛ༻ҙɻαʔόʔͷ)PTU EFW TUBHF ͳͲΛมߋɻ w

    HJU 4PVSDF5SFF  HJUIVC HJUIVCJTTVFT w NBTUFSϒϥϯνͷΈɻ w ཤྺ͑͞ݟ͑Ε͹͍͍ͷͰಛʹ෼͚ͳ͍ɻ w ͱ͍͏͔ίϛοτϝοηʔδͷঁࢠྗ͕ߴ͍ɻ
  9. ͍͖ͳΓͰ͕͢ɺ։ൃํ๏ɻ w 9DPEFʹ%FCVH 3FMFBTF 5FTU'MJHIUͭͷϏϧυઃ ఆΛ༻ҙɻαʔόʔͷ)PTU EFW TUBHF ͳͲΛมߋɻ w

    HJU 4PVSDF5SFF  HJUIVC HJUIVCJTTVFT w NBTUFSϒϥϯνͷΈɻ w ཤྺ͑͞ݟ͑Ε͹͍͍ͷͰಛʹ෼͚ͳ͍ɻ w ͱ͍͏͔ίϛοτϝοηʔδͷঁࢠྗ͕ߴ͍ɻ w ϦϦʔεޙʹNBTUFSͱSFMFBTFʹ෼͚Δ͔΋ɻ
  10. ͍͖ͳΓͰ͕͢ɺ։ൃํ๏ɻ w 9DPEFʹ%FCVH 3FMFBTF 5FTU'MJHIUͭͷϏϧυઃ ఆΛ༻ҙɻαʔόʔͷ)PTU EFW TUBHF ͳͲΛมߋɻ w

    HJU 4PVSDF5SFF  HJUIVC HJUIVCJTTVFT w NBTUFSϒϥϯνͷΈɻ w ཤྺ͑͞ݟ͑Ε͹͍͍ͷͰಛʹ෼͚ͳ͍ɻ w ͱ͍͏͔ίϛοτϝοηʔδͷঁࢠྗ͕ߴ͍ɻ w ϦϦʔεޙʹNBTUFSͱSFMFBTFʹ෼͚Δ͔΋ɻ w Ͱ΋UBHͰे෼͔΋͠Εͳ͍ɻ
  11. Part II. Beatroboղମ৽ॻ • Yusuke Ito @novi_ • about.me/yusukeito •

    http://github.com/novi • LTCoreText (ॎॻ͖ϥΠϒϥϦͳͲ) • yusukeito.me (σβΠϯύλʔϯͷ࿩)
  12. iOS൛։ൃମ੍ • ίʔσΟϯά: 2ਓ • Yusuke Sugamiya, Yusuke Ito •

    ͏ͪ1ਓUIσόοά৬ਓ (Sugamiya) • UIσβΠϯ&ΞʔτϫʔΫ: 1ਓ
  13. ෼୲ • Sugamiya • UIपΓ • ViewController, View, Storyboardͷฤू •

    Ito • ઃܭ΍ϞσϧͳͲ • ଞ Networking, Utils, ࠶ੜ, Ξχϝʔγϣϯ PlaygroundView(+VC), ͦͷଞ
  14. ModelͱNetworkingʹ͍ͭͯ Concept • WebαʔϏεͷΫϥΠΞϯτ • HTTP REST API Λୟ͘ •

    ಡΈ΍͢͞΍ఔΑ͍݁߹Λॏࢹ • কདྷΛߟ͑͗͢ͳ͍ઃܭ
  15. Case Study • e.g. HTTP REST API “/user” • URI:

    https://api.beatrobo.com/user • Ϣʔβʔ ࣗ෼ ͷ৘ใ(name, id, email...)ΛGet, Update͢ΔAPI
  16. Case Study • e.g. HTTP REST API “/user” • URI:

    https://api.beatrobo.com/user • Ϣʔβʔ ࣗ෼ ͷ৘ใ(name, id, email...)ΛGet, Update͢ΔAPI • Get 㱺 GET, Update 㱺 PUT
  17. Case Study • e.g. HTTP REST API “/user” • URI:

    https://api.beatrobo.com/user • Ϣʔβʔ ࣗ෼ ͷ৘ใ(name, id, email...)ΛGet, Update͢ΔAPI • Get 㱺 GET, Update 㱺 PUT • GET /user ↓
  18. Case Study • e.g. HTTP REST API “/user” • URI:

    https://api.beatrobo.com/user • Ϣʔβʔ ࣗ෼ ͷ৘ใ(name, id, email...)ΛGet, Update͢ΔAPI • Get 㱺 GET, Update 㱺 PUT • GET /user ↓ {“id” : “54321”, “name” : “Yusuke I”, “email”: “[email protected]”... }
  19. BRRequest iOSͷTWRequestʹ͍ۙ BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet params:nil]; [req

    sendRequestWithCallback:^ (BRAPIResponse* res) { 1઀ଓ͝ͱʹੜ੒ ಺෦ͰHTTPϦΫΤετΛੜ੒ɾૹड ৴ɾ݁ՌͷJSONΛύʔε
  20. BRRequest iOSͷTWRequestʹ͍ۙ BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet params:nil]; [req

    sendRequestWithCallback:^ (BRAPIResponse* res) { if (res.success) { 1઀ଓ͝ͱʹੜ੒ ಺෦ͰHTTPϦΫΤετΛੜ੒ɾૹड ৴ɾ݁ՌͷJSONΛύʔε
  21. BRRequest iOSͷTWRequestʹ͍ۙ BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet params:nil]; [req

    sendRequestWithCallback:^ (BRAPIResponse* res) { if (res.success) { NSLog(@”result=%@”, res.json); 1઀ଓ͝ͱʹੜ੒ ಺෦ͰHTTPϦΫΤετΛੜ੒ɾૹड ৴ɾ݁ՌͷJSONΛύʔε
  22. BRRequest iOSͷTWRequestʹ͍ۙ BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet params:nil]; [req

    sendRequestWithCallback:^ (BRAPIResponse* res) { if (res.success) { NSLog(@”result=%@”, res.json); } else { 1઀ଓ͝ͱʹੜ੒ ಺෦ͰHTTPϦΫΤετΛੜ੒ɾૹड ৴ɾ݁ՌͷJSONΛύʔε
  23. BRRequest iOSͷTWRequestʹ͍ۙ BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet params:nil]; [req

    sendRequestWithCallback:^ (BRAPIResponse* res) { if (res.success) { NSLog(@”result=%@”, res.json); } else { NSLog(@”failed %@”, res.error); 1઀ଓ͝ͱʹੜ੒ ಺෦ͰHTTPϦΫΤετΛੜ੒ɾૹड ৴ɾ݁ՌͷJSONΛύʔε
  24. BRRequest iOSͷTWRequestʹ͍ۙ BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet params:nil]; [req

    sendRequestWithCallback:^ (BRAPIResponse* res) { if (res.success) { NSLog(@”result=%@”, res.json); } else { NSLog(@”failed %@”, res.error); } 1઀ଓ͝ͱʹੜ੒ ಺෦ͰHTTPϦΫΤετΛੜ੒ɾૹड ৴ɾ݁ՌͷJSONΛύʔε
  25. BRRequest iOSͷTWRequestʹ͍ۙ BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet params:nil]; [req

    sendRequestWithCallback:^ (BRAPIResponse* res) { if (res.success) { NSLog(@”result=%@”, res.json); } else { NSLog(@”failed %@”, res.error); } }]; 1઀ଓ͝ͱʹੜ੒ ಺෦ͰHTTPϦΫΤετΛੜ੒ɾૹड ৴ɾ݁ՌͷJSONΛύʔε
  26. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) Model
  27. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) -(BRUser*)initWithUserID:(NSString*)uid; // ಛఆͷϢʔβʔ Model
  28. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) -(BRUser*)initWithUserID:(NSString*)uid; // ಛఆͷϢʔβʔ // HTTP API /user GET Λୟ͘ Model
  29. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) -(BRUser*)initWithUserID:(NSString*)uid; // ಛఆͷϢʔβʔ // HTTP API /user GET Λୟ͘ -(void)getUserInfoWithCallback:(void(^)(BOOL success))... Model
  30. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) -(BRUser*)initWithUserID:(NSString*)uid; // ಛఆͷϢʔβʔ // HTTP API /user GET Λୟ͘ -(void)getUserInfoWithCallback:(void(^)(BOOL success))... // HTTP API /user PUT Λୟ͘ Model
  31. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) -(BRUser*)initWithUserID:(NSString*)uid; // ಛఆͷϢʔβʔ // HTTP API /user GET Λୟ͘ -(void)getUserInfoWithCallback:(void(^)(BOOL success))... // HTTP API /user PUT Λୟ͘ // data͕HTTPͰ౤͛Δσʔλ Model
  32. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) -(BRUser*)initWithUserID:(NSString*)uid; // ಛఆͷϢʔβʔ // HTTP API /user GET Λୟ͘ -(void)getUserInfoWithCallback:(void(^)(BOOL success))... // HTTP API /user PUT Λୟ͘ // data͕HTTPͰ౤͛Δσʔλ -(void)updateUserInfo:(Dictionary*)data callback:... Model
  33. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) -(BRUser*)initWithUserID:(NSString*)uid; // ಛఆͷϢʔβʔ // HTTP API /user GET Λୟ͘ -(void)getUserInfoWithCallback:(void(^)(BOOL success))... // HTTP API /user PUT Λୟ͘ // data͕HTTPͰ౤͛Δσʔλ -(void)updateUserInfo:(Dictionary*)data callback:... Model
  34. @property NSString* userName; @property NSString* userID; @interface BRUser() { //

    Πϯελϯεม਺ NSDictionary* _data; // αʔόʔAPI(“/user”)͔Βड͚औͬͨσʔλ }
  35. @property NSString* userName; @property NSString* userID; @interface BRUser() { //

    Πϯελϯεม਺ NSDictionary* _data; // αʔόʔAPI(“/user”)͔Βड͚औͬͨσʔλ } -(NSString*)userName { return [_data objectForKey:@”user_name”]; }
  36. @property NSString* userName; @property NSString* userID; @interface BRUser() { //

    Πϯελϯεม਺ NSDictionary* _data; // αʔόʔAPI(“/user”)͔Βड͚औͬͨσʔλ } -(NSString*)userID { return [_data objectForKey:@”id”]; } -(NSString*)userName { return [_data objectForKey:@”user_name”]; }
  37. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) -(BRUser*)initWithUserID:(NSString*)uid; // ಛఆͷϢʔβʔ // HTTP API /user GET Λୟ͘ -(void)getUserInfoWithCallback:(void(^)(BOOL success))... // HTTP API /user PUT Λୟ͘ // data͕HTTPͰ౤͛Δσʔλ -(void)updateUserInfo:(Dictionary*)data callback:... Model
  38. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) -(BRUser*)initWithUserID:(NSString*)uid; // ಛఆͷϢʔβʔ // HTTP API /user GET Λୟ͘ -(void)getUserInfoWithCallback:(void(^)(BOOL success))... // HTTP API /user PUT Λୟ͘ // data͕HTTPͰ౤͛Δσʔλ -(void)updateUserInfo:(Dictionary*)data callback:... Model
  39. - (void)getUserInfoWithCallback:(void(^)(BOOL success))callback { BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet

    params:nil]; [req sendRequestWithCallback:^ (BRAPIResponse* res) { if ( ! res.success) { // Τϥʔ࣌ callback(NO); return; } _data = (NSDictionary*)[res.json copy]; callback(YES); [[NSNotificationCenter defaultCenter] postNotification:BRUserUserInfoDidRefreshNotification object:self]; return; }]; } σʔλΛGET͢ΔAPI (HTTP API /user GET Λୟ͘)
  40. - (void)getUserInfoWithCallback:(void(^)(BOOL success))callback { BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet

    params:nil]; [req sendRequestWithCallback:^ (BRAPIResponse* res) { if ( ! res.success) { // Τϥʔ࣌ callback(NO); return; } _data = (NSDictionary*)[res.json copy]; callback(YES); [[NSNotificationCenter defaultCenter] postNotification:BRUserUserInfoDidRefreshNotification object:self]; return; }]; } σʔλΛGET͢ΔAPI (HTTP API /user GET Λୟ͘)
  41. - (void)getUserInfoWithCallback:(void(^)(BOOL success))callback { BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet

    params:nil]; [req sendRequestWithCallback:^ (BRAPIResponse* res) { if ( ! res.success) { // Τϥʔ࣌ callback(NO); return; } _data = (NSDictionary*)[res.json copy]; callback(YES); [[NSNotificationCenter defaultCenter] postNotification:BRUserUserInfoDidRefreshNotification object:self]; return; }]; } σʔλΛGET͢ΔAPI (HTTP API /user GET Λୟ͘)
  42. - (void)getUserInfoWithCallback:(void(^)(BOOL success))callback { BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet

    params:nil]; [req sendRequestWithCallback:^ (BRAPIResponse* res) { if ( ! res.success) { // Τϥʔ࣌ callback(NO); return; } _data = (NSDictionary*)[res.json copy]; callback(YES); [[NSNotificationCenter defaultCenter] postNotification:BRUserUserInfoDidRefreshNotification object:self]; return; }]; } σʔλΛGET͢ΔAPI (HTTP API /user GET Λୟ͘)
  43. - (void)getUserInfoWithCallback:(void(^)(BOOL success))callback { BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet

    params:nil]; [req sendRequestWithCallback:^ (BRAPIResponse* res) { if ( ! res.success) { // Τϥʔ࣌ callback(NO); return; } _data = (NSDictionary*)[res.json copy]; callback(YES); [[NSNotificationCenter defaultCenter] postNotification:BRUserUserInfoDidRefreshNotification object:self]; return; }]; } σʔλΛGET͢ΔAPI (HTTP API /user GET Λୟ͘)
  44. - (void)getUserInfoWithCallback:(void(^)(BOOL success))callback { BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet

    params:nil]; [req sendRequestWithCallback:^ (BRAPIResponse* res) { if ( ! res.success) { // Τϥʔ࣌ callback(NO); return; } _data = (NSDictionary*)[res.json copy]; callback(YES); [[NSNotificationCenter defaultCenter] postNotification:BRUserUserInfoDidRefreshNotification object:self]; return; }]; } ! ผͷͱ͜ΖͰߋ৽ͷ௨஌Λड͚औΓ͍ͨͱ͖ʹ࢖͏ e.g. UIతʹଞͷViewControllerͷViewͰϢʔβʔ໊Λද͍ࣔͯ͠Δ σʔλΛGET͢ΔAPI (HTTP API /user GET Λୟ͘)
  45. -(id)init { ... self.user = [BRUser me]; ... -(void)viewWillAppear {

    [super viewWillAppear]; [self refreshMyInfo]; } UserInfoViewController Ϣʔβʔͷ৘ใΛऔಘ
  46. -(id)init { ... self.user = [BRUser me]; ... -(void)viewWillAppear {

    [super viewWillAppear]; [self refreshMyInfo]; } UserInfoViewController Ϣʔβʔͷ৘ใΛऔಘ
  47. -(id)init { ... self.user = [BRUser me]; ... -(void)viewWillAppear {

    [super viewWillAppear]; [self refreshMyInfo]; } UserInfoViewController Ϣʔβʔͷ৘ใΛऔಘ
  48. -(id)init { ... self.user = [BRUser me]; ... -(void)viewWillAppear {

    [super viewWillAppear]; [self refreshMyInfo]; } UserInfoViewController Ϣʔβʔͷ৘ใΛऔಘ -(void)refreshMyInfo { [self.user getUserInfoWithCallback:^(BOOL success) { if (success) { // औಘͨ͠Ϣʔβʔ໊Ληοτ self.userNameLabel.text = self.user.userName; } }]; }
  49. -(id)init { ... self.user = [BRUser me]; ... -(void)viewWillAppear {

    [super viewWillAppear]; [self refreshMyInfo]; } UserInfoViewController Ϣʔβʔͷ৘ใΛऔಘ -(void)refreshMyInfo { [self.user getUserInfoWithCallback:^(BOOL success) { if (success) { // औಘͨ͠Ϣʔβʔ໊Ληοτ self.userNameLabel.text = self.user.userName; } }]; }
  50. -(void)doneButtonTapped:(id)sender { NSDictionary* data = @{@”user_name”: self.userNameField.text}; self.doneButton.enabled = NO;

    [self.user updateUserInfo:data callback:^(BOOL success) { if (success) { // ໭Δ or ViewControllerΛด͡Δ } else { // Τϥʔ →AlertView self.doneButton.enabled = YES; } }];
  51. -(void)doneButtonTapped:(id)sender { NSDictionary* data = @{@”user_name”: self.userNameField.text}; self.doneButton.enabled = NO;

    [self.user updateUserInfo:data callback:^(BOOL success) { if (success) { // ໭Δ or ViewControllerΛด͡Δ } else { // Τϥʔ →AlertView self.doneButton.enabled = YES; } }];
  52. -(void)doneButtonTapped:(id)sender { NSDictionary* data = @{@”user_name”: self.userNameField.text}; self.doneButton.enabled = NO;

    [self.user updateUserInfo:data callback:^(BOOL success) { if (success) { // ໭Δ or ViewControllerΛด͡Δ } else { // Τϥʔ →AlertView self.doneButton.enabled = YES; } }];
  53. -(void)doneButtonTapped:(id)sender { NSDictionary* data = @{@”user_name”: self.userNameField.text}; self.doneButton.enabled = NO;

    [self.user updateUserInfo:data callback:^(BOOL success) { if (success) { // ໭Δ or ViewControllerΛด͡Δ } else { // Τϥʔ →AlertView self.doneButton.enabled = YES; } }];
  54. -(void)doneButtonTapped:(id)sender { NSDictionary* data = @{@”user_name”: self.userNameField.text}; self.doneButton.enabled = NO;

    [self.user updateUserInfo:data callback:^(BOOL success) { if (success) { // ໭Δ or ViewControllerΛด͡Δ } else { // Τϥʔ →AlertView self.doneButton.enabled = YES; } }]; • CallbackͰ΋ଟॏݺͼग़͠ͳͲ͕ى͖ʹ͍͘Α͏ʹ
  55. ࢖༻ϥΠϒϥϦ • ͱ͘ʹͳ͠ • ISRefreshControl (pull to refresh for iOS5)

    • ٯʹ෭࡞༻͕͋ΔΑ͏ͳBlocksͳΜͱ͔ͳͲ͸ ࢖Θͳ͍Α͏ʹ͍ͯ͠Δ • XXNetworkingKit΋ࠓͷͱ͜Ζ࢖͍ͬͯͳ͍