Pro Yearly is on sale from $80 to $50! »

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

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

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

2013/2/23 at GREE
"conferenceWithDevelopers"

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

6d2a4ee4d3194f525d5dcc9f1a7433bd?s=128

Yusuke SUGAMIYA

February 23, 2013
Tweet

Transcript

  1. None
  2. ͍͔ʹͯ͠ϢʔβʔΛखۄʹऔΔ͔ ʙϢʔβʔͷߦಈͷࡾखઌΛಡΜͰ࣮૷͢Δʙ Yusuke Sugamiya / @DNPP

  3. Կ΍ͬͯΔਓͳͷʁ w ͜͜Ұ೥͘Β͍J04͹͔ͬॻ͍ͯΔɻ w ͦΕ·Ͱ͸3VCZͱ͔)5.-$44ͱ͔ɻ w ͦͷલ͸%51σβΠφͬΆ͍͜ͱͯͨ͠ɻ w झຯͰΞφϩάͷԻڹܥͷిࢠ޻࡞ͱ͔ɻ w

    ࢀߟIUUQNBLFCPPUIDPNJ3OK w IUUQEOQQPSH͔ΒେମḷΕΔɻ
  4. ϓϨθϯͷλΠτϧɺ ͋Ε͸Ͳ͏ߟ͑ͯ΋௼Γ΍Ζʜɻ

  5. ࠓ೔͸6*ͷ࿩Λ͠·͢ɻ

  6. ࢝Ίʹɻ

  7. 6*ʹ͍ͭͯޠΓग़͢ਓؒɺ େମ஍ཕͩͱࢥ͏ɻ

  8. Կނɺ஍ཕͳͷ͔ɻ ʮطଘͷ΋ͷΛͳΜͱ͔ͯ͠࢖͍΍͍ͨ͘͢͠ʯ ͬͯͱ͕͜ग़ൃ఺ͩͱ͢Δͱɺ

  9. Կނɺ஍ཕͳͷ͔ɻ w େମԡ͠෇͚͕·͘͠ͳΔɻ w ͦΕɺ୯ʹ͓લͷ޷ΈͳͷͰ͸ɻ w มԽΛຊ౰ʹϢʔβʔ͕๬ΜͰΔͷʁ ʮطଘͷ΋ͷΛͳΜͱ͔ͯ͠࢖͍΍͍ͨ͘͢͠ʯ ͬͯͱ͕͜ग़ൃ఺ͩͱ͢Δͱɺ

  10. ͦ΋ͦ΋αʔϏε΍ΞϓϦͷઃܭͱ͔ํ਑Λ ϛε͍ͬͯΔ໰୊Ͱ͋Δ͜ͱ͕ଟ͍ɻ

  11. ޙखޙख͡ΌΜɻ

  12. ໰୊ͷϨΠϠ͕ҧ͏ͷͰ ͓࿩͢Δ͜ͱ͸ແ͍Ͱ͢ɻ

  13. ຊ୊ɻ

  14. None
  15. 6*ͷ࿩Λ͠·͢ɻ

  16. 6*पΓͷΤϯδχΞ͕͢΂͖࢓ࣄɻ

  17. 6*पΓͷΤϯδχΞ͕͢΂͖࢓ࣄɻ w ϢʔβʔʹԾॳΊͷશೳײΛ༩͑Δ͜ͱɻ

  18. 6*पΓͷΤϯδχΞ͕͢΂͖࢓ࣄɻ w ϢʔβʔʹԾॳΊͷશೳײΛ༩͑Δ͜ͱɻ w ࡞ͬͯΔԶΒ͕ຊ౰ͷਆͩʂ

  19. 6*पΓͷΤϯδχΞ͕͢΂͖࢓ࣄɻ w ϢʔβʔʹԾॳΊͷશೳײΛ༩͑Δ͜ͱɻ w ࡞ͬͯΔԶΒ͕ຊ౰ͷਆͩʂ w ๻ୡ͕ਆͩͱ͍͏͜ͱΛϢʔβʔʹඍਖ΋ ؾ෇͔ͤͳ͍͜ͱ͕େࣄɻ

  20. ͳͥؾ෇͔ͤͳ͍͜ͱ͕େࣄͳͷ͔ɻ https://twitter.com/DNPP/status/298114844798906368

  21. Ϣʔβʔ͕΍Γ͍ͨࣄͷࡾखઌΛҙࣝ͢Δɻ

  22. Ϣʔβʔ͕΍Γ͍ͨࣄͷࡾखઌΛҙࣝ͢Δɻ ˠ͜ͷૢ࡞͕དྷͨͱ͍͏͜ͱ͸ɺ͜͏͍͏ಈ࡞Λ ظ଴͍ͯ͠Δ͸ͣͩɺͱ͍͏஌͕ࣝඞཁɻ

  23. Ϣʔβʔςετ͕େࣄɻ

  24. Ϣʔβʔςετ͕େࣄɻ w ಈըʹ࿥Δɻ

  25. Ϣʔβʔςετ͕େࣄɻ w ಈըʹ࿥Δɻ w Ͳ͜Λݟ͍ͯΔ͔ɻ

  26. Ϣʔβʔςετ͕େࣄɻ w ಈըʹ࿥Δɻ w Ͳ͜Λݟ͍ͯΔ͔ɻ w ࢦઌͷ໎͍ํɺࢹઢͷ໎͍ํɺҰ൪࠷ॳ ʹͲ͜ΛݟΔ͔ɺ৮Δ͔ɺද৘ͷมԽɻ

  27. Ϣʔβʔςετ͕େࣄɻ w ಈըʹ࿥Δɻ w Ͳ͜Λݟ͍ͯΔ͔ɻ w ࢦઌͷ໎͍ํɺࢹઢͷ໎͍ํɺҰ൪࠷ॳ ʹͲ͜ΛݟΔ͔ɺ৮Δ͔ɺද৘ͷมԽɻ w ͋Εͬɺ͜ΕͬͯঁͷࢠΛޱઆ͘ͱ͖΋ಉ

    ͜͡ͱ΍Δؾ͕͢Δͳʜɻ
  28. Ϣʔβʔςετ͕େࣄɻ w ಈըʹ࿥Δɻ w Ͳ͜Λݟ͍ͯΔ͔ɻ w ࢦઌͷ໎͍ํɺࢹઢͷ໎͍ํɺҰ൪࠷ॳ ʹͲ͜ΛݟΔ͔ɺ৮Δ͔ɺද৘ͷมԽɻ w ͋Εͬɺ͜ΕͬͯঁͷࢠΛޱઆ͘ͱ͖΋ಉ

    ͜͡ͱ΍Δؾ͕͢Δͳʜɻ w ͖͞΄ͲͷπΠʔτʹࢸΔɻ
  29. ۩ମతʹɺͲ͏͢Ε͹Ϣʔβʔʹ ԾॳΊͷશೳײΛ༩͑ΒΕΔͷ͔ɻ

  30. ૢ࡞ग़དྷͦ͏ͳͱ͜Ζ͕ શ෦ૢ࡞ग़དྷΔɻ

  31. ͍΍ɺ͜Ε೉͍͠ΜͰ͢Αɻ

  32. Ͳ͏͍͏͜ͱͳͷ͔ɻ

  33. ৘ใͷදࣔͷ֊૚ʹໃ६Λ࡞Βͳ͍ɻ ࣮͸ͱͯ΋೉͍͠ɻจԽతͳ΋ͷ΋͋Δ͠ɺ໌จԽ͞Εͯͳ͍৔߹΋ଟ͍ɻ ։ൃऀͷੑೳ͕Ұ൪ݦஶʹग़Δɻ

  34. ৘ใͷදࣔͷ֊૚ʹໃ६Λ࡞Βͳ͍ɻ w Ξχϝʔγϣϯ͕ऴΘ͔ͬͯΒૢ࡞͢Δͷ͔ɺҰॹʹૢ࡞ ͢Δͷ͔ɺҰॹʹऴΘΔͷ͔ɺͦ΋ͦ΋ͦͷΞχϝʔγϣ ϯ͸దਖ਼ͳͷ͔ɻ ࣮͸ͱͯ΋೉͍͠ɻจԽతͳ΋ͷ΋͋Δ͠ɺ໌จԽ͞Εͯͳ͍৔߹΋ଟ͍ɻ ։ൃऀͷੑೳ͕Ұ൪ݦஶʹग़Δɻ

  35. ৘ใͷදࣔͷ֊૚ʹໃ६Λ࡞Βͳ͍ɻ w Ξχϝʔγϣϯ͕ऴΘ͔ͬͯΒૢ࡞͢Δͷ͔ɺҰॹʹૢ࡞ ͢Δͷ͔ɺҰॹʹऴΘΔͷ͔ɺͦ΋ͦ΋ͦͷΞχϝʔγϣ ϯ͸దਖ਼ͳͷ͔ɻ w Ұॹʹ࢝·ΔɺҰॹʹऴΘΔͱ͍͏ͷ͸ɺ࣌ؒ࣠తͳҙຯ ߹͍ͷͱ͖΋͋Ε͹ɺײ֮తͳҙຯ߹͍ͷͱ͖΋͋Δɻ ࣮͸ͱͯ΋೉͍͠ɻจԽతͳ΋ͷ΋͋Δ͠ɺ໌จԽ͞Εͯͳ͍৔߹΋ଟ͍ɻ ։ൃऀͷੑೳ͕Ұ൪ݦஶʹग़Δɻ

  36. ৘ใͷදࣔͷ֊૚ʹໃ६Λ࡞Βͳ͍ɻ w Ξχϝʔγϣϯ͕ऴΘ͔ͬͯΒૢ࡞͢Δͷ͔ɺҰॹʹૢ࡞ ͢Δͷ͔ɺҰॹʹऴΘΔͷ͔ɺͦ΋ͦ΋ͦͷΞχϝʔγϣ ϯ͸దਖ਼ͳͷ͔ɻ w Ұॹʹ࢝·ΔɺҰॹʹऴΘΔͱ͍͏ͷ͸ɺ࣌ؒ࣠తͳҙຯ ߹͍ͷͱ͖΋͋Ε͹ɺײ֮తͳҙຯ߹͍ͷͱ͖΋͋Δɻ w ͦͷӨʹໃ६͸ແ͍͔ɺϨΠϠͷॏͳΓॱ͸ਖ਼͍͔͠ɻ

    ࣮͸ͱͯ΋೉͍͠ɻจԽతͳ΋ͷ΋͋Δ͠ɺ໌จԽ͞Εͯͳ͍৔߹΋ଟ͍ɻ ։ൃऀͷੑೳ͕Ұ൪ݦஶʹग़Δɻ
  37. ෆ҆ΛἤΒͳ͍Α͏ʹ͢Δɻ ࣮૷ͯ͠Δؒ͸೉͍͠ɻ ࡞ͬͨਓؒ͸ʮ͜͏͢Ε͹͜͏ͳΔʯͬͯطʹ෼͔ͬͯΔ͔Βɻ

  38. ෆ҆ΛἤΒͳ͍Α͏ʹ͢Δɻ w ૢ࡞ʹର͢ΔϑΟʔυόοΫ͕ແ͍ɻ ࣮૷ͯ͠Δؒ͸೉͍͠ɻ ࡞ͬͨਓؒ͸ʮ͜͏͢Ε͹͜͏ͳΔʯͬͯطʹ෼͔ͬͯΔ͔Βɻ

  39. ෆ҆ΛἤΒͳ͍Α͏ʹ͢Δɻ w ૢ࡞ʹର͢ΔϑΟʔυόοΫ͕ແ͍ɻ w ௨৴ͯ͠Δͷ͔Կ΋ͯ͠ͳ͍ͷ͔۠ผग़དྷͳ͍ɻ ࣮૷ͯ͠Δؒ͸೉͍͠ɻ ࡞ͬͨਓؒ͸ʮ͜͏͢Ε͹͜͏ͳΔʯͬͯطʹ෼͔ͬͯΔ͔Βɻ

  40. ෆ҆ΛἤΒͳ͍Α͏ʹ͢Δɻ w ૢ࡞ʹର͢ΔϑΟʔυόοΫ͕ແ͍ɻ w ௨৴ͯ͠Δͷ͔Կ΋ͯ͠ͳ͍ͷ͔۠ผग़དྷͳ͍ɻ w ཪͰ஋͕উखʹมΘͬͯΔͬΆ͍ڍಈ͕දͰݟ͑Δɻ ࣮૷ͯ͠Δؒ͸೉͍͠ɻ ࡞ͬͨਓؒ͸ʮ͜͏͢Ε͹͜͏ͳΔʯͬͯطʹ෼͔ͬͯΔ͔Βɻ

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

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

    Ϙλϯ͕͋Δͷʹԡͤͳ͍ɻ ࣮૷ͯ͠Δؒ͸೉͍͠ɻ ࡞ͬͨਓؒ͸ʮ͜͏͢Ε͹͜͏ͳΔʯͬͯطʹ෼͔ͬͯΔ͔Βɻ
  43. ෆ҆ΛἤΒͳ͍Α͏ʹ͢Δɻ w ૢ࡞ʹର͢ΔϑΟʔυόοΫ͕ແ͍ɻ w ௨৴ͯ͠Δͷ͔Կ΋ͯ͠ͳ͍ͷ͔۠ผग़དྷͳ͍ɻ w ཪͰ஋͕উखʹมΘͬͯΔͬΆ͍ڍಈ͕දͰݟ͑Δɻ w Ұॠදࣔ͞ΕͯɺԿ΋ݴΘͣʹඇදࣔʹͳΔɻ w

    Ϙλϯ͕͋Δͷʹԡͤͳ͍ɻ w ಺༰͕Α͘෼͔Βͳ͍ΤϥʔΞϥʔτ͕ग़Δɻ ࣮૷ͯ͠Δؒ͸೉͍͠ɻ ࡞ͬͨਓؒ͸ʮ͜͏͢Ε͹͜͏ͳΔʯͬͯطʹ෼͔ͬͯΔ͔Βɻ
  44. ͜͜·Ͱ͸ ʮͳʹΛͯ͠͸͍͚ͳ͍͔ʯ ͱ͍͏࿩ɻ

  45. ʮͳʹΛ͢Δͱ͍͍͔ʯ ͱ͍͏࿩͸ແ͍ͷ͔ɻ

  46. ͜Ε͸Ұݴɺ ʮ༡ͼ৺Λશ։ʹ͢Δʯ ʹਚ͖·͢ɻ

  47. Ϣʔβʔ͕ෆշʹࢥ͏͜ͱɺշײʹࢥ͏͜ͱɺͷೋͭ ͷύϥϝλ͕͋Δ৔߹ɺΤϯδχΞͷ๻౳͸ ʮϢʔβʔ͕ෆշʹࢥ͏͜ͱΛ࠷খԽ͢ Δͱ͍͏੍໿৚݅ͷݩɺշײʹࢥ͏͜ͱ Λ࠷େԽ͢Δ໰୊ʯ Λղܾ͢΂͖ɺͩͱࢥ͏ɻ

  48. ͜ͷลΓ͔ΒஈʑͱJ04ͷ࿩ʹγϑτɻ ϚϧνλονՄೳͰ͋Δ͜ͱΛલఏʹߟ͑Α͏ɻ

  49. ๻͕͜ͷޙɺ͜ͷ৔Ͱݴ͍͍ͨ͜ͱͷཁ఺Λઌʹɻ

  50. ๻͕͜ͷޙɺ͜ͷ৔Ͱݴ͍͍ͨ͜ͱͷཁ఺Λઌʹɻ ͜͜Λಈ͔ͯ͠Δɺ͜͜Λλονͯ͠Δͬͯͱ ͖ʹ࿔ΒΕΔͱϠό͍ɺมͳ͜ͱʹͳͬͯࠔΔ ৔ॴ͸ͪΌΜͱϩοΫ͠Α͏ͥɻ

  51. ͪͳΈʹɺ͜ΕΛଵΔͱ࠷ѱͷ৔߹ɺ وํͷΞϓϦ͸མͪΔɻ

  52. ຊ౰͔Αɻ w QPQ7JFX$POUSPMMFS͕ൃՐ͢ΔΠϕϯτ ͱɺQSFTFOU7JFX$POUSPMMFSͰNPEBM͕ ൃՐ͢ΔΠϕϯτ͕΄΅ಉ࣌ʹىͬͯ͜ɺ NPEBMͷEFMFHBUFઌͷWJFX$POUSPMMFS ͕QPQͪ͠Ό͔ͬͨΒطʹແͯ͘ղ์ࡁ ΈɺͳΜͯ৔߹ʹམͪ·͢ɻͨͿΜɻ

  53. ώοτςετɺಉ࣌ԡ͠ͱ ࿈ଧΛඞͣ΍Ζ͏ɻ

  54. ๻ୡ͕࢖͑Δಓ۩ɻ

  55. 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
  56. 6*(FTUVSF3FDPHOJ[FSͷ͓࿩

  57. 6*(FTUVSF3FDPHOJ[FSͷ͓࿩

  58. w ͱͯ΋ศརɻ 6*(FTUVSF3FDPHOJ[FSͷ͓࿩

  59. w ͱͯ΋ศརɻ w ᠘͕ଟ͍ɻ 6*(FTUVSF3FDPHOJ[FSͷ͓࿩

  60. w ͱͯ΋ศརɻ w ᠘͕ଟ͍ɻ w FOVNͷ6*(FTUVSF3FDPHOJ[FS4UBUFล ΓͰఆٛ͞ΕͯΔঢ়ଶભҠͱ͔ɺओཁͳ QSPQFSUZʹ͍ͭͯ͸΋͏ϦϑΝϨϯεಡΊ ͱ͔͠ɻ 6*(FTUVSF3FDPHOJ[FSͷ͓࿩

  61. 6*1BO(FTUVSF3FDPHOJ[FSͱ͔ 6*-POH1SFTT(FTUVSF3FDPHOJ[FSͰ 6*(FTUVSF3FDPHOJ[FS4UBUF$IBOHFEͳ࣌ɺ ͪ͜Βଆ͔Β໌ࣔతʹDBODFMΛൃߦ͍ͨ͠ɻ

  62. "QQMFʮͦΜͳͷແ͍Αʯ

  63. None
  64. ·͔͡Αɻ

  65. ࣍ͷ༷ʹ͢ΔͱDBODFM͕ HFTUVSF3FDPHOJ[FSѼʹ ൃߦ͞Ε·͢

  66. gestureRecognizer.enabled = NO; gestureRecognizer.enabled = YES;

  67. None
  68. ʂʂʂόουϊ΢ϋ΢ʂʂʂ

  69. 6*(FTUVSF3FDPHOJ[FS%FMFHBUFͷ͓࿩ɻ w ͪΌΜͱ΍Γ͍ͨΜ͚ͩͲɺ͕࣌ؒʜɻ w ͪͳΈʹ݁ߏѻ͍ਏ͍ͷͰɺॲཧͷྲྀΕͱ ͔λονΠϕϯτॲཧͷ࢓૊Έͱ͔͖ͪΜ ͱ೺Ѳͯ͠ͳ͍ͱ٧Ή͠ɺ಺෦తʹ΋ݺ͹ ΕͯͨΓ͢ΔͷͰɺ6*4DSPMM7JFXͷαϒΫ ϥεΛ࡞ͬͨΓ͢Δͱ͖͸஫ҙ͕ඞཁͰϠ ό͍Ͱ͢ɻʢޙड़͠·͢ʣ

  70. ͜Ε͸J04Ͱ͸௚ͬͯΔΜ͚ͩͲɺ J04Ͱ͸6*(FTUVSF3FDPHOJ[FSΛׂΓ౰ͯ ͨWJFXͷɺλονΛड͚औΔ༏ઌॱং͕͓͔͠ ͍ͱ͍͏໰୊͕͋Γ·ͯ͠ɻ

  71. ਌WJFXʹHFTUVSF3FDPHOJ[FSׂΓ౰ͯͯΔঢ়ଶɻ ͦͷTVCWJFXʹ6*#VUUPOͳͲͷ6*$POUSPMܥͷ΋ ͷ͕͋ͬͨͱ͖ɺͦ΋ͦ΋λονΠϕϯτ͕TVCWJFX ʹ͋Δ6*$POUSPMଆʹҰ੾དྷͳ͍ɻ

  72. ͦΜͳόΧͳɻ

  73. ࣍ͷ༷ʹ͢Δͱճආग़དྷ·͢ɻ

  74. - (BOOL)gestureRecognizer: (UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch { // iOS 6 Ͱ͸ඞཁͳ͍… if

    (touch.view != gestureRecognizer.view && [touch.view isKindOfClass:[UIControl class]]) { return NO; } // ޙ͸ී௨ʹॻ͘…
  75. None
  76. ι΢ϧδΣϜ͕ʜɻ

  77. 6*4DSPMM7JFXลΓͷ͓࿩ɻ

  78. 6*4DSPMM7JFXลΓͷ͓࿩ɻ w ϦϑΝϨϯεΛಡΊɻ

  79. 6*4DSPMM7JFXลΓͷ͓࿩ɻ w ϦϑΝϨϯεΛಡΊɻ w EFMFHBUFϝιουͷݺ͹ΕΔॱ൪ɺݺ͹Ε ΔλΠϛϯάΛਖ਼͘͠ཧղ͢΂͖ɻ

  80. 6*4DSPMM7JFXลΓͷ͓࿩ɻ w ϦϑΝϨϯεΛಡΊɻ w EFMFHBUFϝιουͷݺ͹ΕΔॱ൪ɺݺ͹Ε ΔλΠϛϯάΛਖ਼͘͠ཧղ͢΂͖ɻ w ͦ͏͢Ε͹ͳΜͩͬͯग़དྷΔʂ

  81. 6*4DSPMM7JFXลΓͷ͓࿩ɻ w ϦϑΝϨϯεΛಡΊɻ w EFMFHBUFϝιουͷݺ͹ΕΔॱ൪ɺݺ͹Ε ΔλΠϛϯάΛਖ਼͘͠ཧղ͢΂͖ɻ w ͦ͏͢Ε͹ͳΜͩͬͯग़དྷΔʂ w ֤छQSPQFSUZͷҙຯ߹͍Λਖ਼͘͠ཧղ͢

    ΂͖ɻ
  82. // Ϣʔβͷࢦ͕σόΠεը໘ͱ઀৮͍ͯ͠Δ৔߹ɺ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;
  83. 6*4DSPMM7JFX%FMFHBUFͷγʔέϯεʹ͍ͭͯɻ

  84. 6*4DSPMM7JFX%FMFHBUFͷγʔέϯεʹ͍ͭͯɻ w ͜Εੌ͍େࣄͰɺͲͷλΠϛϯάʹݺ͹Ε Δ͔Λશ෦׬ᘳʹ೺Ѳ͓͚ͯ͠͹ɺ࠷దͳ λΠϛϯάͰଞͷ6*ύʔπͷϩοΫͱղ আ͕ग़དྷΔɻ

  85. 6*4DSPMM7JFX%FMFHBUFͷγʔέϯεʹ͍ͭͯɻ w ͜Εੌ͍େࣄͰɺͲͷλΠϛϯάʹݺ͹Ε Δ͔Λશ෦׬ᘳʹ೺Ѳ͓͚ͯ͠͹ɺ࠷దͳ λΠϛϯάͰଞͷ6*ύʔπͷϩοΫͱղ আ͕ग़དྷΔɻ w େࣄͳ͜ͱͳͷͰೋճݴ͍·ͨ͠ɻ

  86. Ϣʔβʔ͕ը໘ʹλον͢Δ ↓ ͙͢ʹ 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: ͕ݺ͹ΕͯγʔέϯεऴΘΓɻ
  87. 6*4DSPMM7JFXΛͨͩ୯ʹλοϓͩ ͚ͯ͠Ұ੾ࢦΛಈ͔ͣ͞ʹ཭͢ͱ͔ɺ ͦ͏͍͏ςετ΋͠·͠ΐ͏ɻ

  88. Ͳͷஈ֊ͰͲͷ6*ύʔπΛ ϩοΫ͢Δ͔ɻ ͜ͷόϥϯεײ͕֮େࣄɻ

  89. ͔ͳΓࡉ͔͘ࢦఆग़དྷΔɻ ද্ࣔ΍৘ใͷ֊૚Ͱໃ६͕ແ͍Α͏ʹ͠·͠ΐ͏ɻ TDSPMM7JFX%JE&OE%FDFMFSBUJOH·Ͱ଴ͭͱ͔ͳΓ ௕࣌ؒϩοΫ͞ΕΔͷͰɺجຊతʹಈ͍ͯΔ΋ͷΛ ࿔ͬͯ΋େৎ෉ͳઃܭʹ͓ͯ͘͠ͷ͕͍͍ɻ

  90. [PPNͷ࿩΋͋ΔΜ͚ͩͲɺ͕࣌ؒʜɻ

  91. ͪ͜Βଆ͔Β6*4DSPMM7JFXΛ ੍ޚ͍ͨ͠λΠϛϯά͕͋Δɻ ଞͷWJFXͷૢ࡞தͱ͔ʹɻ ׳ੑεΫϩʔϧͷ࠷தͩͬͨΓ͢Δ͜ͱ΋ ͋Δ͠ɺׂͱ૝ఆ͢΂͖ঢ়ଶ͕ଟ͍ɻ

  92. ͬͪ͜ଆͰTDSPMMͷΩϟϯηϧΛ͍ͨ͠ͱ͖͕ɺ ͨ·ʹ͋Δɻ

  93. "QQMFʮͦΜͳͷແ͍Αʯ

  94. ʜ࢓ํແ͍ɻ [scrollView setContentOffset:scrollView.contentOffset animated:NO]; ͱ͔΍͓͍ͬͯͯ׳ੑεΫϩʔϧΛࢭΊͯ΍ͬͨޙʹɺ @property(nonatomic, getter=isScrollEnabled) BOOL scrollEnabled; Λ࿔ͬͯ΍Ε͹ϩοΫग़དྷΔɻ

  95. 6*4DSPMM7JFXͷαϒΫϥεΛ࡞ͬͨΒ 6*(FTUVSF3FDPHOJ[FS%FMFHBUF͕಺ ෦తʹݺ͹Εͯͯࠔͬͨ࿩ɻ

  96. ͜ͷ࿩͸Ϡόͦ͏ͳؾ΋͢ΔͷͰճආίʔυ͚ͩɻ

  97. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gr shouldReceiveTouch:(UITouch *)touch { BRDLOG(@"%@", NSStringFromClass([gr class])); //

    ΄ͱ͹͠ΔΞϨͳײ͡… if ([NSStringFromClass([gr class]) hasPrefix:@"UIScrollView"]) { return YES; } // ޙ͸ී௨ʹ࣮૷…
  98. None
  99. ʂʂʂόουϊ΢ϋ΢ʂʂʂ

  100. ·ͱΊΔͱ ʮ6*(FTUVSF3FDPHOJ[FS%FMFHBUF 6*4DSPMM7JFX%FMFHBUFͱ͓༑ୡʹͳΖ͏ʯ ͱ͍͏͓࿩Ͱͨ͠ɻ ·͍͔ͩͭ͘#,ͳ࿩͸͋ΔΜ͚ͩͲɺͦ͏͍͏ͷ͸ ࠙਌ձͰञͷπϚϛʹͰ΋ͳΕ͹͘Β͍ͳ΋Μɻ

  101. 6*7JFXͷ͓࿩ɻ

  102. 6*7JFXͷ͓࿩ɻ w 6*7JFXͷBOJNBUJPOखܰͰศར͚ͩͲɺΞχ ϝʔγϣϯத΋λονΠϕϯτरͬͪΌ͏ͷ Ͱɺ͔ͬ͠ΓϩοΫͯ͠DPNQMFUJPOͰղআ͠ ·͠ΐ͏ɻ

  103. 6*7JFXͷ͓࿩ɻ w 6*7JFXͷBOJNBUJPOखܰͰศར͚ͩͲɺΞχ ϝʔγϣϯத΋λονΠϕϯτरͬͪΌ͏ͷ Ͱɺ͔ͬ͠ΓϩοΫͯ͠DPNQMFUJPOͰղআ͠ ·͠ΐ͏ɻ w VTFS*OUFSBDUJPO&OBCMFEͳΜ͚ͩͲɺ͜Ε͸ Ϣʔβʔଆ͔Βݟͯݟͨ໨ʹԿ΋มԽ͕ແ͍͔ Βɺ࢖͑Δͱ͜ΖͰ͸ग़དྷΔ͚ͩ6*$POUSPMͷ

    FOBCMFEΛ࿔ͬͯ΍ͬͨํ͕਌੾ɻ
  104. 6*7JFX$POUSPMMFSͷ͓࿩ɻ

  105. J04ͰҰ൪ෳࡶരൃ͕ͪ͠ͳͱ͜Ζɻ ෳࡶ͞ΛͲ͏΍ͬͯճආ͢Δ͔ɻ

  106. J04ͰҰ൪ෳࡶരൃ͕ͪ͠ͳͱ͜Ζɻ ෳࡶ͞ΛͲ͏΍ͬͯճආ͢Δ͔ɻ w ෭࡞༻ͷແ͍ϝιουΛॻ͚ɻ

  107. J04ͰҰ൪ෳࡶരൃ͕ͪ͠ͳͱ͜Ζɻ ෳࡶ͞ΛͲ͏΍ͬͯճආ͢Δ͔ɻ w ෭࡞༻ͷແ͍ϝιουΛॻ͚ɻ w ঢ়ଶΛม͑ͳ͖ΌͳΒͳ͍ͱ͖ɺ͜Ε͑͞ ΍Ε͹҆શʹWJFXͷঢ়ଶ͕ม͑ΒΕΔͱ ͍͏ϝιουΛ࡞Εɻ

  108. J04ͰҰ൪ෳࡶരൃ͕ͪ͠ͳͱ͜Ζɻ ෳࡶ͞ΛͲ͏΍ͬͯճආ͢Δ͔ɻ w ෭࡞༻ͷແ͍ϝιουΛॻ͚ɻ w ঢ়ଶΛม͑ͳ͖ΌͳΒͳ͍ͱ͖ɺ͜Ε͑͞ ΍Ε͹҆શʹWJFXͷঢ়ଶ͕ม͑ΒΕΔͱ ͍͏ϝιουΛ࡞Εɻ w ඪ४Ͱఏڙ͞Ε͍ͯΔ΋ͷͷ࢖͍ํͷཧղ

    ΛਂΊΖɻ
  109. ๻͕Α͘࢖͏ख๏ɻ

  110. ΠϯλʔϑΣʔε෦෼ʹ͜͏ॻ͘ɻ typedef enum { BRHogeViewControllerUndefinedMode, BRHogeViewControllerTrackListMode, BRHogeViewControllerProfileMode, } BRHogeViewControllerMode; @property

    (nonatomic, assign) BRHogeViewControllerMode mode;
  111. ಺෦ͷTFUUFSʹू໿͢Δɻ - (void)setMode:(BRHogeViewControllerMode)mode { // mode ͷอ࣋ͱ͔ɻ // ঢ়ଶΛ҆શʹม͑ΔͨΊʹ༻ҙͨ͠ϝιουΛୟ͘ɻ }

  112. ͋·Γू໿ͤ͗͢͞Δͷ΋ࠔΓ΋ͷ Ͱɺػೳͱ͔໨తຖʹϓϥΠϕʔτϝ ιουʹ΄ͲΑ͘෼͚Δͷ͕ྑ͍ɻ ͜ͷลͷόϥϯεײ֮ΛϛεΔͱϝϯ ςग़དྷͳ͘ͳ͍͖ͬͯ·͢Ͷʜɻ

  113. ϝιουͷ໊લ͕େࣄɻ

  114. ϝιουͷ໊લ͕େࣄɻ ͱ͍͏͔શମతʹ໊લ͕େࣄͩ ΑͶͱ͍͏࿩͸͋Δɻ

  115. ͜͜·ͰϢʔβʔ͔Β ݟ͑Δදଆͷ࿩Ͱ͕ͨ͠ɺ

  116. ͔͜͜ΒɺͦΕΛ࣮ݱ͢Δ ͨΊͷཪଆͷ࣮૷ͷ࿩Λɻ

  117. ͍͖ͳΓͰ͕͢ɺ։ൃํ๏ɻ

  118. ͍͖ͳΓͰ͕͢ɺ։ൃํ๏ɻ w 9DPEFʹ%FCVH 3FMFBTF 5FTU'MJHIUͭͷϏϧυઃ ఆΛ༻ҙɻαʔόʔͷ)PTU EFW TUBHF ͳͲΛมߋɻ

  119. ͍͖ͳΓͰ͕͢ɺ։ൃํ๏ɻ w 9DPEFʹ%FCVH 3FMFBTF 5FTU'MJHIUͭͷϏϧυઃ ఆΛ༻ҙɻαʔόʔͷ)PTU EFW TUBHF ͳͲΛมߋɻ w

    HJU 4PVSDF5SFF  HJUIVC HJUIVCJTTVFT
  120. ͍͖ͳΓͰ͕͢ɺ։ൃํ๏ɻ w 9DPEFʹ%FCVH 3FMFBTF 5FTU'MJHIUͭͷϏϧυઃ ఆΛ༻ҙɻαʔόʔͷ)PTU EFW TUBHF ͳͲΛมߋɻ w

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

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

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

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

    HJU 4PVSDF5SFF  HJUIVC HJUIVCJTTVFT w NBTUFSϒϥϯνͷΈɻ w ཤྺ͑͞ݟ͑Ε͹͍͍ͷͰಛʹ෼͚ͳ͍ɻ w ͱ͍͏͔ίϛοτϝοηʔδͷঁࢠྗ͕ߴ͍ɻ w ϦϦʔεޙʹNBTUFSͱSFMFBTFʹ෼͚Δ͔΋ɻ w Ͱ΋UBHͰे෼͔΋͠Εͳ͍ɻ
  125. Μ͡Ό͋ɺΑΖ͘͠ɻ

  126. Part II. Beatroboղମ৽ॻ • Yusuke Ito @novi_ • about.me/yusukeito •

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

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

    Ito • ઃܭ΍ϞσϧͳͲ • ଞ Networking, Utils, ࠶ੜ, Ξχϝʔγϣϯ PlaygroundView(+VC), ͦͷଞ
  129. None
  130. Playground

  131. Playground • UIScrollView & UIImageView

  132. Playground • UIScrollView & UIImageView • αʔόʔ͔ΒJSONΛऔಘ→ϩϘοτ΍ஔ͖෺ Λੜ੒ (Web൛ͱڞ௨)

  133. Playground • UIScrollView & UIImageView • αʔόʔ͔ΒJSONΛऔಘ→ϩϘοτ΍ஔ͖෺ Λੜ੒ (Web൛ͱڞ௨) •

    ϩϘοτը૾͸αʔόʔଆ͔ΒඇಉظͰಡΈ ࠐΈ (with Ωϟογϡ)
  134. Animation

  135. Animation • CAKeyFrameAnimation

  136. Animation • CAKeyFrameAnimation 1. AfterEffectsͰΞχϝʔγϣϯ࡞੒

  137. Animation • CAKeyFrameAnimation 1. AfterEffectsͰΞχϝʔγϣϯ࡞੒ 2. ৬ਓ ஛Ҫࢯ ͕ΞχϝʔγϣϯΛݟͳ͕ΒFlashʹ ม׵

  138. Animation • CAKeyFrameAnimation 1. AfterEffectsͰΞχϝʔγϣϯ࡞੒ 2. ৬ਓ ஛Ҫࢯ ͕ΞχϝʔγϣϯΛݟͳ͕ΒFlashʹ ม׵

  139. Animation • CAKeyFrameAnimation 1. AfterEffectsͰΞχϝʔγϣϯ࡞੒ 2. ৬ਓ ஛Ҫࢯ ͕ΞχϝʔγϣϯΛݟͳ͕ΒFlashʹ ม׵

    3. Flash→JSON→CAKeyFrameAnimation ࣗಈม׵
  140. ModelͱNetworkingʹ͍ͭͯ Concept

  141. ModelͱNetworkingʹ͍ͭͯ Concept • WebαʔϏεͷΫϥΠΞϯτ

  142. ModelͱNetworkingʹ͍ͭͯ Concept • WebαʔϏεͷΫϥΠΞϯτ • HTTP REST API Λୟ͘

  143. ModelͱNetworkingʹ͍ͭͯ Concept • WebαʔϏεͷΫϥΠΞϯτ • HTTP REST API Λୟ͘ •

    ಡΈ΍͢͞΍ఔΑ͍݁߹Λॏࢹ
  144. ModelͱNetworkingʹ͍ͭͯ Concept • WebαʔϏεͷΫϥΠΞϯτ • HTTP REST API Λୟ͘ •

    ಡΈ΍͢͞΍ఔΑ͍݁߹Λॏࢹ • কདྷΛߟ͑͗͢ͳ͍ઃܭ
  145. Case Study

  146. Case Study • e.g. HTTP REST API “/user”

  147. Case Study • e.g. HTTP REST API “/user” • URI:

    https://api.beatrobo.com/user
  148. Case Study • e.g. HTTP REST API “/user” • URI:

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

    https://api.beatrobo.com/user • Ϣʔβʔ ࣗ෼ ͷ৘ใ(name, id, email...)ΛGet, Update͢ΔAPI • Get 㱺 GET, Update 㱺 PUT
  150. 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 ↓
  151. 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”: “hoge@gmail.com”... }
  152. UserInfoViewController BRUser Model Πϯελϯεม਺ͱͯ͠อ࣋

  153. NSURLConnection UserInfoViewController BRUser Model BRRequest Connection ݺͼग़͢ ݺͼग़͢ Πϯελϯεม਺ͱͯ͠อ࣋

  154. BRRequest

  155. BRRequest iOSͷTWRequestʹ͍ۙ

  156. BRRequest iOSͷTWRequestʹ͍ۙ 1઀ଓ͝ͱʹੜ੒

  157. BRRequest iOSͷTWRequestʹ͍ۙ 1઀ଓ͝ͱʹੜ੒ ಺෦ͰHTTPϦΫΤετΛੜ੒ɾૹड ৴ɾ݁ՌͷJSONΛύʔε

  158. BRRequest iOSͷTWRequestʹ͍ۙ BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet params:nil]; 1઀ଓ͝ͱʹੜ੒

    ಺෦ͰHTTPϦΫΤετΛੜ੒ɾૹड ৴ɾ݁ՌͷJSONΛύʔε
  159. BRRequest iOSͷTWRequestʹ͍ۙ BRRequest* req = [BRRequest requestWithAPI:@”/user” method:BRRequestMethodGet params:nil]; [req

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

    sendRequestWithCallback:^ (BRAPIResponse* res) { if (res.success) { 1઀ଓ͝ͱʹੜ੒ ಺෦ͰHTTPϦΫΤετΛੜ੒ɾૹड ৴ɾ݁ՌͷJSONΛύʔε
  161. 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Λύʔε
  162. 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Λύʔε
  163. 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Λύʔε
  164. 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Λύʔε
  165. 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Λύʔε
  166. BRUser Model

  167. BRUser @interface BRUser : NSObject Model

  168. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; Model

  169. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

    (readonly...) NSString* userID; Model
  170. BRUser @interface BRUser : NSObject @property (readonly...) NSString* userName; @property

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

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

    (readonly...) NSString* userID; +(BRUser*)me; // ৗʹࣗ෼ͷBRUserΛฦ͢ (γϯάϧτϯ) -(BRUser*)initWithUserID:(NSString*)uid; // ಛఆͷϢʔβʔ // HTTP API /user GET Λୟ͘ Model
  173. 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
  174. 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
  175. 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
  176. 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
  177. 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
  178. None
  179. @interface BRUser() { // Πϯελϯεม਺ NSDictionary* _data; // αʔόʔAPI(“/user”)͔Βड͚औͬͨσʔλ }

  180. @property NSString* userName; @property NSString* userID; @interface BRUser() { //

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

    Πϯελϯεม਺ NSDictionary* _data; // αʔόʔAPI(“/user”)͔Βड͚औͬͨσʔλ } -(NSString*)userName { return [_data objectForKey:@”user_name”]; }
  182. @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”]; }
  183. 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
  184. 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
  185. - (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 Λୟ͘)
  186. - (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 Λୟ͘)
  187. - (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 Λୟ͘)
  188. - (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 Λୟ͘)
  189. - (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 Λୟ͘)
  190. - (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 Λୟ͘)
  191. Model (BRUser)ΛViewController͔Β࢖͏ UserInfoViewController BRUser

  192. UserInfoViewController Ϣʔβʔͷ৘ใΛऔಘ

  193. -(id)init { ... self.user = [BRUser me]; ... -(void)viewWillAppear {

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

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

    [super viewWillAppear]; [self refreshMyInfo]; } UserInfoViewController Ϣʔβʔͷ৘ใΛऔಘ
  196. -(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; } }]; }
  197. -(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; } }]; }
  198. UserInfoViewController Ϣʔβʔͷ৘ใΛ Ξοϓσʔτ

  199. UserInfoViewController Ϣʔβʔͷ৘ใΛ Ξοϓσʔτ self.doneButton

  200. UserInfoViewController Ϣʔβʔͷ৘ใΛ Ξοϓσʔτ self.doneButton self.userNameField

  201. -(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; } }];
  202. -(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; } }];
  203. -(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; } }];
  204. -(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; } }];
  205. -(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Ͱ΋ଟॏݺͼग़͠ͳͲ͕ى͖ʹ͍͘Α͏ʹ
  206. Α͍ͱ͜Ζ

  207. Α͍ͱ͜Ζ • ബ͍ͷͰίʔυ͕௥͍΍͍͢

  208. Α͍ͱ͜Ζ • ബ͍ͷͰίʔυ͕௥͍΍͍͢ • σόοάͱ࣮૷ָ͕

  209. Α͍ͱ͜Ζ • ബ͍ͷͰίʔυ͕௥͍΍͍͢ • σόοάͱ࣮૷ָ͕ • ͋Δఔ౓͸֦ு(ϦϑΝΫλϦϯά)͠΍͍͢

  210. Α͍ͱ͜Ζ • ബ͍ͷͰίʔυ͕௥͍΍͍͢ • σόοάͱ࣮૷ָ͕ • ͋Δఔ౓͸֦ு(ϦϑΝΫλϦϯά)͠΍͍͢ • Block಺ͰΩϟϓνϟͨ͠ΦϒδΣΫτ΍selfͷϝ ϞϦ؅ཧ͕ෆཁ

  211. Α͍ͱ͜Ζ • ബ͍ͷͰίʔυ͕௥͍΍͍͢ • σόοάͱ࣮૷ָ͕ • ͋Δఔ౓͸֦ு(ϦϑΝΫλϦϯά)͠΍͍͢ • Block಺ͰΩϟϓνϟͨ͠ΦϒδΣΫτ΍selfͷϝ ϞϦ؅ཧ͕ෆཁ

    • in(refreshUserInfo...)͔Βout(Callback)·Ͱ͕1ຊͳͷ Ͱ໰୊(෭࡞༻)͕গͳ͍(͸ͣ)
  212. ࢖༻ϥΠϒϥϦ • ͱ͘ʹͳ͠ • ISRefreshControl (pull to refresh for iOS5)

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

  214. IUUQBQQCFBUSPCPDPN

  215. Beatrobo for iOS

  216. ઈࢍ։ൃதʂ

  217. ͜͜ʹΞΫηεͯ͠ɺϝʔϧΞυϨε ೖΕ͓͍ͯͯ΋Β͑Ε͹ɺϦϦʔεͷ ͓஌ΒͤΛ͠·͢ʂ

  218. IUUQBQQCFBUSPCPDPN

  219. ͓ΘΓɻ