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

レガシーなアプリケーションの 60fps化を目指す為にやっていること

レガシーなアプリケーションの 60fps化を目指す為にやっていること

iOSDC2018

8/31 17:40
@早稲田大学理工学部 西早稲田キャンパス 63号館

F05557f473bac91b5bdc6c2e8a95c6f2?s=128

satoshin21

August 31, 2018
Tweet

Transcript

  1. Copyright © 2017 eureka, Inc. All rights reserved. What we’ve

    done to get High Performance in our Legacy Application ϨΨγʔͳΞϓϦέʔγϣϯͷ 60fpsԽΛ໨ࢦ͢ҝʹ΍͍ͬͯΔ͜ͱ
  2. Copyright © 2017 eureka, Inc. All rights reserved. 2 Introduce

     FVSFLB *OD  1BJSTJ04"QQMJDBUJPO&OHJOFFS  ໺ྑΧϝϥϚϯ΍ͬͯ·͢ඃࣸମʹծ͑ͯΔͷͰࣸਅࡱΒΕͯԼ͍͞ @satoshin21
  3. Copyright © 2017 eureka, Inc. All rights reserved. 3 Agenda

     1BJSTͷ঺հͱJ04νʔϜͷ՝୊  ॲཧϑϩʔΛ௥͍΍͍͢ΞʔΩςΫνϟͷಋೖ  Ϩεϙϯεͷ࠷దԽಡΈࠐΈ଎౓ߴ଎Խ  ໨ࢦͤGQT$PMMFDUJPO7JFXνϡʔχϯά  Ռͨͯ͠GQTͰվળͨ͠ͷ͔ʁ
  4. Copyright © 2017 eureka, Inc. All rights reserved. Pairsͷ঺հ &

    iOSνʔϜͷ՝୊
  5. None
  6. Copyright © 2017 eureka, Inc. All rights reserved. 6 ྺ࢙Λ࣋ͭPairs

     αʔϏε։࢝͸೥݄  ೥݄ʹ1BJSTGPSJ04W͕ఏڙ։࢝  ೥݄ʹϑϧεΫϥον
  7. Copyright © 2017 eureka, Inc. All rights reserved. 7 2018೥ݱࡏͷ՝୊

     0CKFDUJWF$͕ࠜװΛ୲͍ͬͯΔ෦෼͕͋Δҝɺ4XJGUͷϙςϯγϟϧΛ࠷ େݶੜ͔ͤͳ͍  ػೳ௥Ճɾվળεϐʔυ্͕͕͍ͬͯΔ͕ɺϓϩμΫτ͕ͦͷεϐʔυʹ ௥͍͚͍ͭͯͳ͍  ٕज़ෛ࠴͕ஷ·ΓɺϓϩμΫτͷύϑΥʔϚϯεʹӨڹ͕ग़࢝Ί͍ͯΔ  ͔Β࡞Γ௚͍͕ͨ͠ɺίετ͕ߴ͍
  8. Ͳ͏ʹ͔վળ͍ͨ͠

  9. ͍͖ͳΓશͯΛ࡞Γม͑ΔͷͰ͸ͳ͘ શମ࠷దԽʹ޲͚ͯҰาͮͭਐΉ

  10. Copyright © 2017 eureka, Inc. All rights reserved. 10 શମ࠷దͱ෦෼࠷ద

     શମ࠷ద΁ͷಓ͸ҰͭͰ͸ͳ͍  ෦෼తͳ࠷దԽΛߦ͍ɺͦΕΛϓϩμΫτશମʹల։͍ͯ͘͠  શମ࠷దΛݟਾ͑ͨ෦෼࠷దΛߦ͏
  11. ෦෼࠷దΛ͢ΔͷͰ͋Ε͹ɾɾ

  12. Ϣʔβ͕ޮՌΛ࣮ײ͠΍͍͢ & ໢ཏతͳػೳ͕ଘࡏ͢Δ

  13. ϢʔβΛ͕͢͞ը໘

  14. Copyright © 2017 eureka, Inc. All rights reserved. 14 ͕͢͞ը໘ʹܾΊͨཧ༝

     ϩάΠϯޙɺҰ൪࠷ॳʹදࣔ͞ΕΔը໘  Ϣʔβʹ࠷΋ར༻͞ΕΔը໘ͷҰͭ  ϓϩμΫτ಺Ͱԣల։Մೳͳ༷ʑͳػೳ  $PMMFDUJPO7JFX Ϧϩʔυɺ௥ՃಡΈࠐΈɺ༷ʑͳσʔλΛҰཡදࣔ
  15. Copyright © 2017 eureka, Inc. All rights reserved. 15 ͕͢͞ը໘ͷ՝୊

     ൚༻Խͷҝͷଟ૚ܧঝͰॲཧ͕௥͍ʹ͍͘  Ϣʔβͷσʔλྔ͕ଟ͍ҝɺϩʔυʹ͕͔͔࣌ؒ Δ  εΫϩʔϧ࣌ʹΨλͭ͘  ฏۉdGQT J1IPOFJ04Ͱܭଌ ※ Ϣʔβը૾͸σϞ༻ʹ༻ҙͨ͠΋ͷʹͳΓ·͢
  16. Copyright © 2017 eureka, Inc. All rights reserved. 16 Τ΢ϨΧ

    ͷ iOS/Android/Web Engineer  6*69ʹ߆Γ͕ڧ͍ 6*ψϧψϧܯ࡯͕ৗற   *OTUBHSBN΍5JOEFSͳͲΠέͯΔ6*69Λ໨ࢦ͢
  17. Copyright © 2017 eureka, Inc. All rights reserved. 17 ෦෼࠷దͷ໨ඪ

     ॲཧϑϩʔΛ௥͍΍͍͢ΞʔΩςΫνϟͷಋೖ  ϢʔβͷϨεϙϯεΛ࠷దԽಡΈࠐΈͷߴ଎Խ  ໨ࢦͤGQT
  18. Copyright © 2017 eureka, Inc. All rights reserved. ॲཧϑϩʔΛ௥͍΍͍͢ ΞʔΩςΫνϟͷಋೖ

  19. Copyright © 2017 eureka, Inc. All rights reserved. 19 ݱࡏͷ͕͢͞ը໘

     'BU7JFX$POUSPMMFS  ͕͢͞ը໘Ͱ͸ͭͷ7JFX$POUSPMMFSΛܧঝ͢Δଟ૚ߏ੒
  20. Copyright © 2017 eureka, Inc. All rights reserved. 20 ଟ૚ܧঝ͞ΕΔViewController

    "CTUSBDU 7JFX$POUSPMMFS ͕͢͞ը໘ 7JFX$POUSPMMFS "CTUSBDU 7JFX$POUSPMMFS "CTUSBDU 7JFX$POUSPMMFS "CTUSBDU 7JFX$POUSPMMFS "CTUSBDU 7JFX$POUSPMMFS 6*7JFX$POUSPMMFS
  21. Copyright © 2017 eureka, Inc. All rights reserved. 21 Redux

    with ReSwift  3F4XJGU3F4XJGUΛ༻͍ͨ3FEVY-JLFͳΞʔΩςΫνϟͰ࣮ݧ  ୯Ұํ޲ͷॲཧϑϩʔ  ঢ়ଶͷදݱɾ؅ཧɾมߋͷ੹຿͕෼͚ΒΕ͍ͯΔ  ঢ়ଶΛҰͭʹू໿  ίϯϙʔωϯτΛ֦ு͠΍͍͢࡞Γ https://github.com/ReSwift/ReSwift
  22. https://github.com/ReSwift/ReSwift

  23. 6TFS4FBSDI"DUJPO 6TFS4FBSDI 7JFX$POUSPMMFS "QQ4UPSF "QQ4UBUF 6TFS4FBSDI4UBUF "QQ3FEVDFS 6TFS4FBSDI3FEVDFS .JEEMFXBSF

  24. 6TFS4FBSDI"DUJPO 6TFS4FBSDI 7JFX$POUSPMMFS "QQ4UPSF "QQ4UBUF 6TFS4FBSDI4UBUF "QQ3FEVDFS 6TFS4FBSDI3FEVDFS .JEEMFXBSF

  25. 6TFS4FBSDI"DUJPO 6TFS4FBSDI 7JFX$POUSPMMFS "QQ4UPSF "QQ4UBUF 6TFS4FBSDI4UBUF "QQ3FEVDFS 6TFS4FBSDI3FEVDFS .JEEMFXBSF

  26. 6TFS4FBSDI"DUJPO 6TFS4FBSDI 7JFX$POUSPMMFS "QQ4UPSF "QQ4UBUF 6TFS4FBSDI4UBUF "QQ3FEVDFS 6TFS4FBSDI3FEVDFS .JEEMFXBSF

  27. 6TFS4FBSDI"DUJPO 6TFS4FBSDI 7JFX$POUSPMMFS "QQ4UPSF "QQ4UBUF 6TFS4FBSDI4UBUF "QQ3FEVDFS 6TFS4FBSDI3FEVDFS .JEEMFXBSF

  28. Copyright © 2017 eureka, Inc. All rights reserved. 28 ReSwift࣮૷

     ࣮ࡍͷίʔυʹ͍ͭͯ͸࣌ؒత౎߹্ׂѪ͠·͢  ޙ΄Ͳ4QFBLFS%FDLʹσΟϨΫλʔζΧοτ൛ͱͯ͠ࢿྉΛެ։͠·͢ͷ Ͱɺ͝ࢀߟʹ͍ͯͩ͘͠͞
  29. Copyright © 2017 eureka, Inc. All rights reserved. 29 ReSwiftΛ༻͍ͨReduxͷӡ༻

     ॲཧΛ୯Ұํ޲ʹ͢Δ͜ͱʹΑͬͯɺॲཧϑϩʔΛ௥͍΍͘͢ͳͬͨ  ར༻ଆ͸ɺػೳ௥Ճ࣌ʹؾʹ͢΂͖ࣄ͕ݮͬͨ  Ҏલ͸͋ΒΏΔঢ়ଶΛ͋ΒΏΔॴͰ؅ཧ͍ͯͨ͠  "DUJPO 4UBUF 3FEVDFSͱ੹຿͕෼͚ΒΕ͍ͯΔҝɺ࣮૷ऀؒͷ࢓༷ͷζ Ϩ͕ܰݮ͞Εͨ
  30. Copyright © 2017 eureka, Inc. All rights reserved. ϢʔβͷϨεϙϯεΛ࠷దԽ &

    ಡΈࠐΈͷߴ଎Խ
  31. Copyright © 2017 eureka, Inc. All rights reserved. 31 ϢʔβϨεϙϯεͷ࠷దԽ

     ͕͢͞ը໘ͰϦΫΤετͨ͠Ϣʔβ৘ใ͸͋ΒΏΔ৘ใΛؚΜͰ͍ͨ  ֤ը໘Ͱ࢖͏ҝͷϢʔβͷεςʔτͳͲ  Ϣʔβ৘ใΛੜ੒͢Δҝͷ༨ܭͳෛՙ͕αʔόαΠυʹ  NTd
  32. Copyright © 2017 eureka, Inc. All rights reserved. 32 ϢʔβϨεϙϯεͷ࠷దԽ

     ͕͢͞ը໘ͳͲɺ(SJE6*্Ͱදࣔ͢ΔϢʔβ৘ใʹඞཁ࠷௿ݶͳϨεϙϯ εΛఆٛ  ϢʔβϨεϙϯεΛ൒෼ʹ  εϐʔυվળ  NTNT
  33. Copyright © 2017 eureka, Inc. All rights reserved. 33 Ϣʔβ௥ՃಡΈࠐΈͷ࠷దԽ

     Ұ౓ʹԿ݅ϢʔβΛऔΓࠐΉ͔ɺϢʔβͷૢ࡞Λͳ Δ΂્͘֐͠ͳ͍MJNJU஋Λࢦఆ͍ͨ͠ ӈ͸मਖ਼લ   MJNJU஋Λ୹͗͢Δͱ౎౓ಡΈࠐΈ͕ൃੜ͠ɺ௕͗͢ ΔͱϨΠΞ΢τߋ৽ʹӨڹ͢Δ  ࠓͷॴ݅Λऔಘ͢Δͷ͕ྑͦ͞͏ ※ Ϣʔβը૾͸σϞ༻ʹ༻ҙͨ͠΋ͷʹͳΓ·͢
  34. Copyright © 2017 eureka, Inc. All rights reserved. 34 Ϣʔβ௥ՃಡΈࠐΈͷ࠷దԽ

     ௥ՃಡΈࠐΈͷऔಘλΠϛϯά΋มߋ  ࠓ·Ͱ͸ϖʔδ෼खલ͔ΒϦΫΤετϢʔβΛྲྀ͠ಡΈ͍ͯ͠Δ৔߹ ʹҾ͔͔ͬΓ͕͋ͬͨ  dϖʔδखલ͙Β͍͔ΒϦΫΤετ͢Δͷ͕Αͦ͞͏ʁ
  35. Copyright © 2017 eureka, Inc. All rights reserved. 35 ը૾ಡΈࠐΈߴ଎Խ

     ը૾ͷಡΈࠐΈ଎౓ͷվળ  ը૾ͷಡΈࠐΈλΠϛϯάͷݟ௚͠
  36. Copyright © 2017 eureka, Inc. All rights reserved. 36 ը૾ಡΈࠐΈߴ଎Խ

    with Nuke  LFBO/VLFͷಋೖ  Ұ௨Γͷػೳ͸׬උ  ,JOHpTIFS౳ͱൺ΂ͯ΋ߴ଎   $BDIF΍3FRVFTUपΓͷΧελϚΠζ͕͠΍͍͢ ※ https://qiita.com/H_Crane/items/422811dfc18ae919f8a4
  37. Copyright © 2017 eureka, Inc. All rights reserved. 37 ը૾ಡΈࠐΈߴ଎Խ

    with Nuke https://github.com/kean/Image-Frameworks-Benchmark
  38. Copyright © 2017 eureka, Inc. All rights reserved. 38 ը૾ಡΈࠐΈߴ଎Խ

    with Nuke https://github.com/kean/Image-Frameworks-Benchmark
  39. Copyright © 2017 eureka, Inc. All rights reserved. 39 ը૾ಡΈࠐΈߴ଎Խ

    with Nuke Nuke.loadImage( with: ImageRequest(url: url), options: ImageLoadingOptions( transition: .fadeIn(duration: 0.33) ), into: imageView) // That’s it!
  40. Copyright © 2017 eureka, Inc. All rights reserved. 40 Nuke

    with Prefetch API  J04͔Β6*$PMMFDUJPO7JFX%BUB4PVSDF1SFGFUDIJOH͕࢖͑Δ  1SFGFUDIJOH /VLF*NBHF1SFIFBUFS  XJMM%JTQMBZGPS*UFN"UͰ͍ͯͨ͠ը૾ߋ৽ΛDFMM'PS*UFN"UͰߦ͏Α͏ʹ มߋ  J04͔Βݺ͹ΕΔλΠϛϯά͕มΘͬͨ ͱͷ͜ͱ͚ͩͲ΋ɾɾʁ
  41. Copyright © 2017 eureka, Inc. All rights reserved. 41 Prefetching

    + Nuke.ImagePreheater extension UserSearchViewController: UICollectionViewDataSourcePrefetching { fileprivate let preheater: Nuke.ImagePreheater func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) { DispatchQueue(label: "scene.discovery.vc.prefetch").async { [weak self] in let requests: [Nuke.ImageRequest] = indexPaths.map({..}) self?.preheater.startPreheating(with: requests) } } func collectionView(_ collectionView: UICollectionView, cancelPrefetchingForItemsAt indexPaths: [IndexPath]) { preheater.stopPreheating() } }
  42. Copyright © 2017 eureka, Inc. All rights reserved. 42 Prefetching

    + Nuke.ImagePreheater extension UserSearchViewController: UICollectionViewDataSourcePrefetching { fileprivate let preheater: Nuke.ImagePreheater func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) { DispatchQueue(label: "scene.discovery.vc.prefetch").async { [weak self] in let requests: [Nuke.ImageRequest] = indexPaths.map({..}) self?.preheater.startPreheating(with: requests) } } func collectionView(_ collectionView: UICollectionView, cancelPrefetchingForItemsAt indexPaths: [IndexPath]) { preheater.stopPreheating() } }
  43. Copyright © 2017 eureka, Inc. All rights reserved. 43 Prefetching

    + Nuke.ImagePreheater extension UserSearchViewController: UICollectionViewDataSourcePrefetching { fileprivate let preheater: Nuke.ImagePreheater func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) { DispatchQueue(label: "scene.discovery.vc.prefetch").async { [weak self] in let requests: [Nuke.ImageRequest] = indexPaths.map({..}) self?.preheater.startPreheating(with: requests) } } func collectionView(_ collectionView: UICollectionView, cancelPrefetchingForItemsAt indexPaths: [IndexPath]) { preheater.stopPreheating() } }
  44. Copyright © 2017 eureka, Inc. All rights reserved. 44 ஫ҙ఺

     1SFGFUDI"1*  දࣔ༧ఆͷ͢΂ͯͷ*OEFY1BUI͕౉͞ΕΔ༁Ͱ͸ͳ͍  DFMM'PS*UFN"U  1BJSTͷ؀ڥͰ͸΄΅XJMM%JTQMBZGPS*UFN"Uͱಉ͡λΠϛϯάͩͬͨ  Կ͔͠Βͷ޻෉͕ඞཁ͔΋
  45. Copyright © 2017 eureka, Inc. All rights reserved. 45 ϢʔβͷϨεϙϯε࠷దԽ

    & ը૾ಡΈࠐΈߴ଎Խ  ࠓ·Ͱͷഒऔಘεϐʔυ͕ૣ͍ҝɺϦϑϨογϡɺ௥ՃಡΈࠐΈ࣌ͷετ ϨεΛܰݮ  ը૾ΛεΫϩʔϧ࣌ʹ͙֬͢ೝͰ͖ΔͨΊɺϢʔβ͕͙͢ʹΞΫγϣϯͰ ͖ΔΑ͏ʹͳͬͨ
  46. Copyright © 2017 eureka, Inc. All rights reserved. ໨ࢦͤ60fps

  47. 60fpsͰψϧψϧମݧΛఏڙ͍ͨ͠

  48. None
  49. Copyright © 2017 eureka, Inc. All rights reserved. 49 AutoLayout͸଎߈Ͱ௚͞ͳ͚Ε͹ͳΒͳ͍

     ͔ͳΓޮՌ͕͋ͬͨ ମײ   ͳͥ΍ͬͯͳ͔ͬͨ
  50. Copyright © 2017 eureka, Inc. All rights reserved. 50 Fix

    AutoLayout tips  ·ͣ͸ͳ͓͢΂͖$POTUSBJOUΛ൑ผ͢Δ  /4-BZPVU$POTUSBJOUJEFOUJpFS  7JFX%FCVHHFS 3FWFBM
  51. Copyright © 2017 eureka, Inc. All rights reserved. 51 Fix

    AutoLayout tips - NSLayoutConstraint.identifier  /4-BZPVU$POTUSBJOUʹ͸JEFOUJpFS͕ઃఆՄೳ  ίʔυ্Ͱ΋ઃఆՄ
  52. Copyright © 2017 eureka, Inc. All rights reserved. 52 Fix

    AutoLayout tips - NSLayoutConstraint.identifier
  53. Copyright © 2017 eureka, Inc. All rights reserved. 53 Fix

    AutoLayout tips - View Debugger
  54. Copyright © 2017 eureka, Inc. All rights reserved. 54 Fix

    AutoLayout tips - Reveal  3FWFBMͰ΋ಉ༷ʹ/4-BZPVU$POTUSBJOU ΍7JFXΛΞυϨεͰݕࡧՄೳ  յΕ੍͍ͯͨ໿ΛϚʔΫͯ͘͠ΕΔҝݟ΍ ͍͢
  55. AutoLayout͕յΕͨ৔߹͸ ଎߈Ͱ௚͠·͠ΐ͏

  56. Copyright © 2017 eureka, Inc. All rights reserved. 56 Color

    Blended Layers  7JFX -BZFS ΛॏͶͯඳը͍ͯ͠Δ෦෼  ॏͳΓ߹͏ϨΠϠʔΛൺֱ͠࠷ऴతͳग़ྗ஋Λܭࢉ ͢ΔҝɺඳըύϑΥʔϚϯεʹӨڹ͢Δ
  57. Copyright © 2017 eureka, Inc. All rights reserved. 57 Color

    Blended Layers ֬ೝํ๏  4JNVMBUPSͷ৔߹  .FOV$PMPS#MFOEFE-BZFSTʹνΣοΫ
  58. Copyright © 2017 eureka, Inc. All rights reserved. 58 Color

    Blended Layers ֬ೝ  ࣮ػͷ৔߹ 9DPEF   9DPEF%FCVH7JFX%FCVHHJOH3FOEFSJOH$PMPS#MFOEFE -BZFSTʹνΣοΫ
  59. Copyright © 2017 eureka, Inc. All rights reserved. 59 Color

    Blended Layers ରࡦ - UIImageView  Ͱ͖ΔݶΓCBDLHSPVOE$PMPSΛࢦఆ͢Δ  ಁաը૾ΛͳΔ΂͘࢖Θͳ͍  ະಁաͷΑ͏ͳը૾Ͱ΋BMQIB஋ؚ͕·Ε͍ͯΔ ৔߹͕͋ΔͨΊ஫ҙ
  60. Copyright © 2017 eureka, Inc. All rights reserved. 60 Color

    Blended Layers ରࡦ - UILabel  Ͱ͖ΔݶΓCBDLHSPVOE$PMPSΛࢦఆ͢Δ  DMJQT5P#PVOETΛUSVFʹ  ೔ຊޠɾதࠃޠͳͲΛදࣔ͢Δ৔߹ɺڪΒ͘TVCMBZFS͕௥Ճ͞Ε͍ͯΔ ҝ  ˞EFTDFOU஋͕ਖ਼͘͠ઃఆ͞Ε͍ͯΔTZTUFN'POUʹݶΔ
  61. Copyright © 2017 eureka, Inc. All rights reserved. 61 Color

    Blended Layers ରࡦ - UILabel System Font + clipsToBounds HirakakuProN-W3 + clipsToBounds  MFBEJOH஋Λແࢹͯ͠DMJQ͍ͯ͠Δ https://speakerdeck.com/satoshin21/uifontdescriptor?slide=8 leading஋ͳͲʹ͍ͭͯ͸ɺҎલpotatotipsͰൃදͨ͠ࢿྉΛ͝ࢀߟʹ͍ͯͩ͘͠͞
  62. Copyright © 2017 eureka, Inc. All rights reserved. 62 Offscreen

    Rendering  ؙ֯΍ӨΛεΫϦʔϯ্ʹඳը͢ΔࡍɺϨϯμϦϯάલʹલ΋ͬͯ Φϑε ΫϦʔϯͰ ॲཧΛߦ͏  ϋʔυ΢ΣΞΞΫηϥϨʔγϣϯ (16 Λ࢖༻͍ͯ͠ͳ͍ҝύϑΥʔϚ ϯε௿ԼͷҰҼͱͳΔ  SBTUFSJ[F΋͢΂͖λΠϛϯάͱ͢΂͖Ͱͳ͍λΠϛϯά͕͋Δ  J04Ҏ߱Ͱ͸6**NBHF7JFXͰ࠷దԽ͞Ε͍ͯΔͱ͍͏͕ᷚͩɾɾ
  63. Copyright © 2017 eureka, Inc. All rights reserved. 63 Offscreen

    Rendering - ֬ೝํ๏  $PMPS#MFOEFE-BZFSTͱಉ͡ํࣜͰ 0⒎TDSFFO3FOEFSJOHΛ࣮ߦ͍ͯ͠ΔՕॴΛ৭ ෇͚Ͱ͖Δ
  64. Copyright © 2017 eureka, Inc. All rights reserved. 64 Offscreen

    Rendering - ରࡦ  ؙ֯༻ͷ.BTL7JFXΛ6**NBHF7JFXͷ্ʹ ৐ͤΔํࣜͰ0⒎TDSFFO3FOEFSJOHΛආ͚ͯ ͍Δ  վमલ͔Βߦ͍ͬͯΔҝɺৄࡉ͸ׂѪ ฐࣾͷ ϒϩάΛࢀর͍ͯͩ͘͠͞ https://medium.com/eureka-engineering/iosͷϋΠύϑΥʔϚϯεͳcorner-rounding-strategy-88a43641b554
  65. Copyright © 2017 eureka, Inc. All rights reserved. 65 ࠩ෼ߋ৽

     ݱࡏ͸௥ՃಡΈࠐΈɺ1VMMUP3FGSFTI͢Δͨͼʹ DPMMFDUJPO7JFXSFMPBE%BUB ΛݺΜͰ͍ͨ  SFMPBE%BUB ΛݺͿ͜ͱͰෆඞཁͳWJTJCMF$FMMTͷߋ৽͕࣮ߦ͞ΕΔ
  66. Copyright © 2017 eureka, Inc. All rights reserved. 66 ࠩ෼ߋ৽

    - Libraries  *OTUBHSBN*(-JTU,JU  TFDUJPOϕʔεͷࠩ෼ൺֱ  3Y4XJGU$PNNVOJUZ3Y%BUB4PVSDFT  KqJOUFS%XJ⒎U  NVVLJJ%BUB4PVSDFT
  67. Copyright © 2017 eureka, Inc. All rights reserved. 67 muukii/DataSources

     NVVLJJ%BUB4PVSDFT  *(-JTU,JUͳͲͷࠩ෼நग़ΞϧΰϦζϜΛࢀߟʹ࡞ΒΕ͍ͯΔ  λΠϓηʔϑ  ࠩ෼நग़ʹಛԽͨ͠γϯϓϧͳ࢓૊Έطଘͷ࢓૊Έͱ਌࿨ੑ͕ߴ͍  ฐࣾϝϯόʔ NVVLJJ ͕࡞͍ͬͯΔҝɺ࣭໰͕͋ͬͨΒ͙͢ฉ͚Δ
  68. Copyright © 2017 eureka, Inc. All rights reserved. 68 muukii/DataSources

    - ModelΛఆٛ enum Item { case user(User) case banner(Banner) case feature(Feature) // Ϩίϝϯυ࿮ͷΑ͏ͳ΋ͷ }
  69. Copyright © 2017 eureka, Inc. All rights reserved. 69 muukii/DataSources

    - ModelΛఆٛ import DataSources extension Item: DataSources.Diffable { typealias Identifier = String var diffIdentifier: String { switch self { case .user(let user): return user.diffIdentifier case .banner(let banner): return banner.diffIdentifier case .feature(let feature): return feature.diffIdentifier } } }
  70. Copyright © 2017 eureka, Inc. All rights reserved. 70 muukii/DataSources

    - ModelΛఆٛ import DataSources extension Item: DataSources.Diffable { typealias Identifier = String var diffIdentifier: String { switch self { case .user(let user): return user.diffIdentifier case .banner(let banner): return banner.diffIdentifier case .feature(let feature): return feature.diffIdentifier } } }
  71. Copyright © 2017 eureka, Inc. All rights reserved. 71 muukii/DataSources

    - ModelΛఆٛ import DataSources extension Item: DataSources.Diffable { typealias Identifier = String var diffIdentifier: String { switch self { case .user(let user): return user.diffIdentifier case .banner(let banner): return banner.diffIdentifier case .feature(let feature): return feature.diffIdentifier } } }
  72. Copyright © 2017 eureka, Inc. All rights reserved. 72 muukii/DataSources

    - SectionControllerΛఆٛ final class UserSearchViewController: UIViewController, StoreSubscriber { fileprivate lazy var sectionController: DataSources.SectionDataController<Item, CollectionViewAdapter> = .init( adapter: .init(collectionView: self.collectionView), displayingSection: 0, isEqual: { a, b in a.diffIdentifier == b.diffIdentifier } ) }
  73. Copyright © 2017 eureka, Inc. All rights reserved. 73 muukii/DataSources

    - SectionControllerΛఆٛ final class UserSearchViewController: UIViewController, StoreSubscriber { fileprivate lazy var sectionController: DataSources.SectionDataController<Item, CollectionViewAdapter> = .init( adapter: .init(collectionView: self.collectionView), displayingSection: 0, isEqual: { a, b in a.diffIdentifier == b.diffIdentifier } ) }
  74. Copyright © 2017 eureka, Inc. All rights reserved. 74 muukii/DataSources

    - SectionControllerΛఆٛ final class UserSearchViewController: UIViewController, StoreSubscriber { fileprivate lazy var sectionController: DataSources.SectionDataController<Item, CollectionViewAdapter> = .init( adapter: .init(collectionView: self.collectionView), displayingSection: 0, isEqual: { a, b in a.diffIdentifier == b.diffIdentifier } ) }
  75. Copyright © 2017 eureka, Inc. All rights reserved. 75 muukii/DataSources

    - SectionControllerΛఆٛ final class UserSearchViewController: UIViewController, StoreSubscriber { func newState(state: State) { switch state.loadingState { case .loaded(let items): self.sectionController.update( items: items, updateMode: .partial(animated: true), completion: { Log.info("updated") }) } } }
  76. Copyright © 2017 eureka, Inc. All rights reserved. 76 muukii/DataSources

    - SectionControllerΛఆٛ final class UserSearchViewController: UIViewController, StoreSubscriber { func newState(state: State) { switch state.loadingState { case .loaded(let items): self.sectionController.update( items: items, updateMode: .partial(animated: true), completion: { Log.info("updated") }) } } }
  77. Copyright © 2017 eureka, Inc. All rights reserved. 77 muukii/DataSources

    - SectionControllerΛఆٛ final class UserSearchViewController: UIViewController, StoreSubscriber { func newState(state: State) { switch state.loadingState { case .loaded(let items): self.sectionController.update( items: items, updateMode: .partial(animated: true), completion: { Log.info("updated") }) } } }
  78. 60fpsʹ͚ۙͮͨͷ͔ʁ

  79. ߋ৽લ ߋ৽ޙ iPhone 5(MD297J/A) iOS 10.3.3 ※ Ϣʔβը૾͸σϞ༻ʹ༻ҙͨ͠΋ͷʹͳΓ·͢

  80. ߋ৽લ ߋ৽ޙ 36fps 60fps 55fps iPhone 5(MD297J/A) iOS 10.3.3 ※

    Ϣʔβը૾͸σϞ༻ʹ༻ҙͨ͠΋ͷʹͳΓ·͢
  81. Copyright © 2017 eureka, Inc. All rights reserved. ·ͱΊ

  82. Copyright © 2017 eureka, Inc. All rights reserved. 82 վળ݁Ռ

     ਓؒʹ͸ཧղ͕೉͔ͬͨ͠ॲཧϑϩʔΛ3FEVYΛಋೖ͢Δ͜ͱͰΘ͔Γ΍ ͘͢ఆٛ͢Δ͜ͱ͕Ͱ͖ͨ  ৮͍ͬͯͯ৺஍͍͍6*69Λఏڙ͢Δϕʔε͕Ͱ͖ͨ  GQTΛҰͭͷࢦඪͱ͢Δ͜ͱͰɺ6*69޲্ΛఆྔԽ͢Δ͜ͱ͕Ͱ͖ͨ
  83. Copyright © 2017 eureka, Inc. All rights reserved. 83 օ͞Μʹ͓ئ͍

     Τ΢ϨΧϒʔεΛ༻ҙ͍ͯ͠·͢ʂ  ΋͠ɺύϑΥʔϚϯενϡʔχϯάʹؔͯ͠ڵຯ͕͋Δํɺʮ͜ΕΛվળ ͨ͠ΒύϑΥʔϚϯε޲্ͨ͠ΑʂʯͳͲͷϊ΢ϋ΢͕͋ΔํͳͲ͍Βͬ ͠Ό͍·ͨ͠Βɺੋඇͱ΋৘ใަ׵͠·͠ΐ͏
  84. Thank you IUUQTXXXOBTBHPWNJTTJPO@QBHFT/11OFXTFBSUIBUOJHIUIUNM