ãªã¯ã«ãŒããã¯ãããžãŒãºããGunosyã«è»¢è·ãã
éè·
2014幎12ææ«ããã£ãŠãªã¯ã«ãŒããã¯ãããžãŒãºãéè·ããŸããã ç³ããã°ã©ãã ã£ãç§ã«ãå匷æéãšãµããŒããäžããŠé ããããŸããéçºè ãšããŠå€±æããããã£ã³ã¹ããæçµçã«ã¯ã¹ã¯ã©ã ãã¹ã¿ãŒç圹å²ãŸã§ããããŠé ããã 1幎3ã¶æãšçãæéã§ãããããšãŠãè¯ãçµéšãç©ãããšæã£ãŠããã
èªåã«ãšã£ãŠå°è±¡ã«æ®ã£ãç¹ã¯ã
- 倧äŒæ¥ã®å®å®æãšããªã¯ã«ãŒãçã¹ããŒãæã®ãã©ã³ã¹
- ããžãã¹ã«å¯Ÿããå èŠ
- 人ã倧åã«ãã瀟颚
- æãäžããã°ãããã
- ãŸãã¯ãè©ŠããŠã¿ãããšããæåã
éã«ãæ £ããã«å°ã£ãç¹ã¯ã
- ææã衚瀺ããæãäžããªããšããšã¹ã«ã¬ãŒã¿ãŒåŒã«ããããäºãéã£ãŠããäºã¯ãŸããªã
- è¯ããæªããããã£ã±ãå¶æ¥ã匷ãäŒç€Ÿ
- æ©èœäŒç€ŸãšããŠã®ç«ã¡äœçœ®ïŒå¥ãã¹ãã§è©³ããæžããŸããïŒ
ããææãåºã人ãèŠãŠãããšãåµæ¥è æ±å¯ããã®
èªãæ©äŒãåµãåºããæ©äŒã«ãã£ãŠèªããå€ããã
ãšããèšèãå®çŸã§ããŠãããã©ãããããŒã ã£ããšæããã
éçºè ãšããŠã®ã¿ãªãããèµ·æ¥å®¶çãªé¢ã§ãè¯ã圱é¿ãåããããšãåºæ¥ããšæããç¹ã«ãèªåã®ããžãã¹ããµãŒãã¹ã«å¯ŸããŠç±ãæ³ããæã€äººãå€ããããåŠã³ãšãªã£ãã 人ã«ãæµãŸããæ¬åœã«è¯ãæéãéããããšæã£ãŠããã
ïŒã¡ãªã¿ã«ãå°ã£ãã®ãŒã¯ãªäººãå€ã掻èºããŠããããŠãŒã¶ãŒãå€ãæ±ãããµãŒãã¹ãæè¡é¢ã§æ¯ããŠããã®ã¯åœŒçã®åªåã«ãããäŸãã°ã¢ãã€ã«ã§ã¯ãAndroidã¢ããªéçºãPushåºç€ãªã©ãåèã«ãªãäºäŸã ã
ãã®åŸ
2015幎1æããã¯Gunosyãšãããã¥ãŒã¹ã¢ããªãäœãäŒç€Ÿã§åããŠããã éçºè åå人ã®èœåãšãåžåã®ã¹ããŒãããšãŠãæ©ããè °ãæãããã ã©ããªããŒã ããšãããšããã¶ã€ããiOSã¢ããªãæžããiOSã¢ããªéçºè ãAPIãæžãããããªããŒã ã
æ°ããæè¡ã®æ¡çšã«ãç©æ¥µçã§ãçŸåšAPIã¯Goèšèªã§æžãããŠããããã®èŠæš¡ã®ãããã¯ã·ã§ã³ã§ãåœå ã§Goãæ¬æ Œçã«äœ¿ã£ãŠãããµãŒãã¹ã¯ããããGunosyãããã ããã
ãŸãããªãã£ã¹ãæè¿å æ¬æšãã«ãºã«ç§»è»¢ããå¿«é©ãªç°å¢ã§åããŠè¯ãã
ã¹ã¿ãŒãã¢ãããšããç°å¢ã§æãŸããªãããæè¡é¢ã䌞ã°ããŠããããã ãŸããGunosyã§ã¯æ°ãã仲éãåéããŠããã®ã§ãèå³ãããæ¹ã¯æ¯éã
800万DL突破!Gunosyと共に成長したいiOSエンジニア急募! - Gunosyの新卒・インターンシップ - Wantedly
■iOSエンジニア急募!■GunosyのiOS開発リーダー候補を大募集中! - Gunosyの求人 - Wantedly
iOSã§åç»ã¹ããªãŒãã³ã°ãç°¡åã§ååãªããæ¹ã
åç»ã¹ããªãŒãã³ã°ãå®è£ ããæ©äŒããã£ãã®ã§ããŸãšããã
ããæ¹ã¯å€§ãããããŠïŒã€
- HTTP Live Streaming
- Media Player framework
åè ãçšããå Žåã®åçæ¹æ³ã¯
- AV Foundation framework
- OpenAL framework
ãªã©ããããŸãã
ããããããš
UITableViewCelläžã§ãµãŒããŒäžã«ããåç»ãåçããã
æ¹é
ä»åã®èŠä»¶ãæºããã®ã«ã¯ãMedia Player frameworkã§ååãªã®ã§ãããã䜿ããMPMoviePlayerControllerãšããã¯ã©ã¹ãçšãããããã¯iOS2.0ããããã¯ã©ã¹ãªã®ã§ãããŒãžã§ã³å¯Ÿå¿ãããããªã
Media Player frameworkã䜿ãäžã§ã®æ³šæç¹
- Simulatoräžã§åããããšãåºæ¥ãªãå Žåãããã
- è€æ°ã®åç»ãåæã«åçããäºã¯ã§ããªããMedia Player frameworkã§æ°ããåç»ãåçãå§ãããšããã®çŽåã«åçããŠããåç»ã®ãã£ãã·ã¥ã¯åé€ãããã
- ãããªã®é·ãã10å以äžã5åéã®ããŒã¿éã5MB以äžã§ããã°ãHTTP Live Streamingãçšããå¿ èŠãããã
- ã¢ããªåŽã§åç»ããã¥ãŒãã§ããªã
å®è£
ãŸããviewDidLoad
ã«ãŠMPMoviePlayerController
ãåæåããã
@interface JSKMainTableViewController () @property (nonatomic) MPMoviePlayerController *moviePlayer; @end static NSString *const kURLString = @"https://ia802302.us.archive.org/27/items/Pbtestfilemp4videotestmp4/video_test.mp4"; @implementation JSKMainTableViewController - (void)viewDidLoad { [super viewDidLoad]; self.moviePlayer = [[MPMoviePlayerController alloc] init]; // ã¹ããªãŒãã³ã°ãããã self.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming; self.moviePlayer.contentURL = [NSURL URLWithString:kURLString]; // UITableViewCelläžã«è¡šç€ºãããããåç»æäœããŒãã¯é衚瀺 [self.moviePlayer setControlStyle:MPMovieControlStyleNone]; // åç»ããªããŒããã self.moviePlayer.repeatMode = MPMovieRepeatModeOne; }
ãã®moviePlayerãã- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
ã«ãŠCellã«æž¡ãã
CellForRowAtIndexPath
ã§æž¡ããŠããªãã®ã¯ãStoryboard+AutolayoutãçšããUIViewã®äžã«è²Œãä»ããŠãããããViewãçæãããã®ãåŸ
ã€å¿
èŠãããããã
- (void)layoutWithUrl:(NSString *)url { // 貌ãä»ããäºå®ã®UIViewã®ãµã€ãºãååŸ player.view.frame = _videoSuper.frame; [self.videoSuper addSubview: player.view]; // åç [player prepareToPlay]; [player play]; }
以äžã§åçãã§ããã
Cellã衚瀺ããŠããæã®ã¿åç»åç
ä»åã¯CellãåºçŸããã¿ã€ãã³ã°ã§åçãå®æœãããã£ãã®ã§ãUITableViewCellå
ã®[player play];
ãåé€ããUITableViewã«ä»¥äžãå®è£
ããã
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if ([cell.class isSubclassOfClass:JSKVideoTableViewCell.class]) { // åç»åæ¢ [self.moviePlayer pause]; } } - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if ([cell.class isSubclassOfClass:JSKVideoTableViewCell.class]) { // åç»ã®è²Œãä»ã [(JSKVideoTableViewCell *)cell layoutWithPlayer:self.moviePlayer]; // åç»åç [self.moviePlayer play]; } }
ããã«ãããç»é¢äžã«Cellã衚瀺ãããŠããæã®ã¿åç»ãåçãããã
ãªã¯ã«ãŒããã¯ãããžãŒãºã«æããããŠ
ãã®ãšã³ããªãŒã¯ãæ ªåŒäŒç€Ÿãªã¯ã«ãŒããã¯ãããžãŒãº Advent Calendar 2014ã®25æ¥ç®ã§ãã
ç§ã®æå±ãããªã¯ã«ãŒããã¯ãããžãŒãºã«ã€ããŠãçé¢ç®ã«æžããŠã¿ãã åæãšããŠããªã¯ã«ãŒããã¯ãããžãŒãºã«å ¥ç€Ÿã 1幎 3ãæãããã£ãŠãããèŠèãçãããŸãããã®äŒç€Ÿã§å€ãã®ãã£ã³ã¹ããããæé·ã§ãæè¬ããŠããããããªåæãèžãŸããŠä»¥äžãèªãã§æ¬²ããã
ãã®ç«ã¡äœçœ®
ãªã¯ã«ãŒãã°ã«ãŒãã¯çŸåšãITäŒæ¥ãšããŠã®å€è²ãéãã€ã€ããããã®äžè§ãæ ãã®ããªã¯ã«ãŒããã¯ãããžãŒãºã§ãããITã«ãã競ååªäœæ§æ§ç¯ã®äžå¿ãæ ã£ãŠããã äž»ãªäºæ¥å 容ã¯ããªã¯ã«ãŒãã°ã«ãŒãã®ããžãã¹ã«ãããITã»ãããããŒã±ãã£ã³ã°ãã¯ãããžãŒã®éçºã»æäŸããšãªã£ãŠããããªã¯ã«ãŒãã°ã«ãŒãå šäœã«å¯Ÿããã³ã³ãµã«ãã£ã³ã°ãã¡ãŒã ãæ å ±ã·ã¹ãã éšéçãªåœ¹å²ãæ ã£ãŠãããäžåã®äºæ¥ã¯æãããæè¡æäŸãšããæ©èœïŒâSIerãšç§ã¯è§£éããŠããïŒã®ã¿ããæã£ãŠããã ITäŒæ¥ãžã®é²åã®éæž¡æãšããããšãããããªã¯ã«ãŒããããéšåãšSIerãããéšåãæ··ããåã£ãç¶æ ã ã
ãªã¯ã«ãŒããã¯ãããžãŒãºã®ãªã¯ã«ãŒãããã
ã¹ããŒãæãããã ã¢ããã人æã倧äºã«ããçãªã¯ã«ãŒããããã¯æ©èœäŒç€Ÿã«ãªã£ãŠãæ®ã£ãŠããã
ããã ã¢ãã
æãæãã人ããããããªã¯ã«ãŒãã¯ç€Ÿå¡ççµå¶è 䞻矩ãã€ãŸãå売ã®å匷ãåºæ¥ãäŒç€Ÿã§ãããïŒæ±å¯æµ©æ£ããªã¯ã«ãŒãã®DNAãïŒããããäºããäžé·ã圹å¡ã«ãã¬ãŒã³ãããã®å¹æãããžã«ã«ã«ç€ºãããšãåºæ¥ãã°ããã£ã³ã¹ãè²°ãããããæåããã°ææåéãããã äŸãã°ã2014幎2æã®iOSã¢ããªXcode5ãã«ãå¿ é åæã«ãå ¥ç€Ÿäžã¶æã¡ãã£ãšã®ç§ãåããŸãšããããšæãæãããã£ã¬ã³ãžãããŠããã£ããããŠããã
å§åçåœäºè æè
èªããã³ãããããäºã¯ãåœäºè æèããã£ãŠãããããšããããšãATIãšç¥ãããã¹ã¿ã³ã¹ãšãéãšèšãããå Žåããããããåãªãã©ãããïŒããšèãããäºãå€ãã瀟å ã§æŽ»èºããŠãã人æã¯ããã®åœäºè æèã匷ããã©ããªæã§ãåããŠãããšããå°è±¡ããã£ãã
ãã©ãããªç€Ÿé¢š
ç§ãé å±ãããéšçœ²ã®ãã°ã«ãŒããããŒãžã£ãŒã¯20代ããŸãã圹å¡ã瀟é·ãšãäŒè°äŸé Œãéãã°æ®éã«è©±ã«è¡ãäºãã§ããããŸãã瀟é·å«ãã©ããªäººã«ãããããä»ãã§åŒã¶æåã§ãããæèŠãã¶ã€ããããšãå€ã ããããããŠå ¥ç€Ÿå¹Žæã«é¢ä¿ãªãçã®è¯ãæèŠã§ããã°æ¡çšãããã
å人ã®èœåéçº
ãªã¯ã«ãŒãã°ã«ãŒãå šäœã«èšããããå人ã®èœåéçºã«åŒ·ãåãå ¥ããŠããã2011幎é ããå°å ¥ãããWill Can Mustã·ãŒãããã®ä»çµã®äžã€ã§ãããWillã¯äœãå®çŸãããããCanã¯äœãã§ããã»ã§ããããã«ãªãããã®ããMustã¯éæãã¹ãããã·ã§ã³ã瀺ããŠããããã®Willã«é¢ããŠã¯ãäŒç€Ÿå ã ãã§ãªããèŸããåŸã®äºãèšèŒããã瀟å€ã®æŽ»åãå«ããŠãäžé·æçãªãã£ãªã¢ãäžé·ãäžç·ã«ãªãè°è«ã§ããç°å¢ã¯ä»ã«ã¯ãªãã®ã§ã¯ãªãã ãããã
ãŸããåªç§ãªéçºè ãããã®ã§ããããã人ãã¡ããæåããµããŒããããŠããããç°å¢ã¯ããã£ããã¹ã¿ãŒãã¢ããã«è¡ã£ãŠãããããããªäœè£ã¯ãªãã£ãã ãããå ±éåãšãæšæºåã¿ãããªæèãçãŸãããä»ã¢ããªãäœã£ãŠãäžã§ã®åºç€ã¯ããã§ã»ãšãã©åŠãã ã
ã¹ãããäŒæ
以äžãªã¯ã«ãŒããã¯ãããžãŒãºã®å ¬åŒãŠã§ããµã€ãããåŒçšã
æ倧é£ç¶28æ¥éãå€ç¶3幎以äžã®ç€Ÿå¡ãªã誰ã§ã3幎ããšã«ååŸã§ããé·æäŒæã§ããå¿èº«ããªãã¬ãã·ã¥ããããèªå·±ã®æé·æ©äŒã«ãããªã©ãç®çã¯èªç±ãå ããŠããããå¿æŽããæåœãšããŠäžåŸ30äžåãæ¯çµŠãããŸãã
ããŒãããŒæå
æ¥åå§èšã®äººãã¡ããå€æ³šãšåŒã°ããããŒãããŒãšåŒã¶æåããªã¯ã«ãŒãã«ã¯ããããªã¯ã«ãŒããã¯ãããžãŒãºãäŸå€ã§ã¯ãªããåããµãŒãã¹ãå ±ã«äœã£ãŠãããããŒãããŒã ãããšã®ããšããã®ããŒãããŒãšç€Ÿå¡ã®å¢ç®ãä»ç€Ÿã«æ¯ã¹ããšèãã®ãç¹åŸŽã§ãã°ã«ãŒãã®æŠç¥ããéçºæšé²ãããŒãããŒãæ ã£ãŠãããããããã®ããŒãããŒã®å€§åã¯éåžžã«åªç§ãªäººãå€ããããã®ã³ããã¿ãŒã¿ãããªäººããããšãã
èªç±ãªç€Ÿé¢š
ããã¯éçºè ãšçžæ§ã®è¯ãæåãæè£ èªç±ã§ãã¬ãã¯ã¹å¶ãã³ã¢ã¿ã€ã ãããã°ã«ãŒããããã
瀟å SIerçãªèŠçŽ
ITäŒæ¥ã«çãŸãå€ããçºã«ãããã®èŠçŽ ã¯åŸã ã«å€ãã£ãŠããã®ã ãšæããæ¡çšã«ãåãå ¥ããäžéã§ãŠãŒã¶ãŒäŒæ¥ã§åãããã¿ãããªäººïŒ@hotchemiãšãïŒãéããŠããã®ã§ãããã ã¢ãããªãªã¯ã«ãŒãã®ç€Ÿé¢šãªãæ¹åãããŠããã®ã§ã¯ãšæã£ãŠããã
äºæ¥ãæã£ãŠããªã
æ©èœäŒç€Ÿãªã®ã§ãèªåã®æ ã£ãŠãããµãŒãã¹ã®æ¹éã«å ¥ã蟌ãã«ã¯ãïŒã©ãã®äŒç€Ÿã§ãåãã ãšã¯æããïŒãããªãã®å°äœãç¯ããã倧ããªä¿¡é Œãç²åŸãããããªããšé£ããããã®äººãå§åçåœäºè æèãæã£ãŠããªãéãã¯ããããŸã§äžè«ãSIerãšä»£ãããªãä»äºããåºæ¥ãªãä»çµã¿ã«ãªã£ãŠããŸã£ãŠãããç¹ã«ãªã¯ã«ãŒããããäœè²äŒç³»æåã«éŠŽæããªãéçºè ã¯ããã€ã®ã§ã¯ãšæã£ãŠããã
éçºãããæšé²
ã³ãŒãã£ã³ã°ã¯äžèšã®éãããŒãããŒãå®æœããŠããããšãå€ãããããŸã ãŸã 瀟å¡ã«ã¯æšé²èœåãæ±ããããããšã®æ¹ãå€ããæ°å°ãªãéçºãåºæ¥ã瀟å¡ããã®èæ¯ç¥èãçç±ã«ãçäžãããžã§ã¯ãã«æšé²ãªãŒããŒãšããŠæå ¥ãããŠããã人ãåãããŠäŸ¡å€ãçãæ¹ãã倧ããªäŸ¡å€ãçããšããã®ãåããããéçºè ã§ãããç§ã«ãšã£ãŠã¯æšé²æ¥åãããéçºãããããšæã£ãŠããŸãã
人æ
ç¬ç«ããæ©èœäŒç€Ÿãªã®ã§ãè²»çšèšç®ã¯äººæåäœãšãªããããèªäœæªã ãšæããªãããæ¢ã«å€ãèªãããŠããããã«äººæèšç®ã®ããžãã¹ã¢ãã«èªäœã«ã¯å€§ããªåé¡ç¹ãããã®ã¯æããèªãããŠããããšã
äžæ¬çŽåã®ããžãã¹ã¢ãã«ïœ€å€éè«è² æ§é ãã£ãã§ã³ã·ããªéçºäœå¶
SIerãéè·ããŸãããã
æ¬åœã®SIerãšéãããã®ã¢ãã«ã¯äºæ¥äŒç€Ÿãšã®é¢ä¿æ§ãããŒã«ãã£ã³ã°ã¹ã®äžå£°ã§å€§ããå€ããå¯èœæ§ããããç§ã¯éçºãšäºæ¥ãäžäœã«ãªãå ããããã®ã§ã¯ãšæã£ãŠããã
ãã®ä»äŒããŠããããäº
åœéç人æããŸã ãŸã å°ãªã
æäœéã®è±èªããåãã人æãå°ãªããå šç€Ÿå¡ãéãŸãäŒã§ãè±èªã¯åããªããŠããæµ·å€åºåŒµå€§äžå€«ã§ãããã£ãŠèããæã«ã¯ãé ãçããªã£ããéã«ãåœé人æã«ãšã£ãŠã¯ãã£ã³ã¹ãã€ãã¿ãããç°å¢ã§ã¯ãããçŸã«ãç§ã¯äžå¹Žéã«äºåæµ·å€åºåŒµã«æŽ»ãããŠè²°ã£ãŠããè¡ã£ãŠããããã ããåœé人ãåãååã«çºæ®åºæ¥ãç°å¢ãã§èšããšæªãããæµ·å€ã®å£²äžãå¢ãããŠãããšã¯èšãããªã¯ã«ãŒãã°ã«ãŒãã®äž»ãªå£²äžã¯åœå ã®ã¡ãã£ã¢ã§ãããç¹ã«ãªã¯ã«ãŒããã¯ãããžãŒãºãä¿ãé åã¯ãã¡ã¹ãã£ãã¯ãªé åãå€ããä»åŸãããã°ã«ãŒãå šäœã®æè¡åãæ¯ããäŒæ¥ãšããŠãåœéçãªæè¡è ã®æ¡çšã¯å¿ é ã ãšèããŠããã
å®å¹ŽãŸã§åãã
ãªã¯ã«ãŒããã¯ãããžãŒãºå ¥ç€Ÿæã«ãå®å¹ŽãŸã§åããç°å¢ãæ瀺ãããããšèšããã³ã£ããããããªã¯ã«ãŒãã¯äžå¹Žã§èŸããŠç¬ç«ããããã®äŒç€Ÿããšæã£ãŠããããã ããªã¯ã«ãŒããã¯ãããžãŒãºã§ã¯ãç¬ç«æ¯æŽã®å¶åºŠããããé·ãåãããšãåæã«ããéè·éå¶åºŠãšãªã£ãŠããããããããªã¯ã«ãŒãããããšSIerãããã®æ··ããåã£ãäžæè°ãªæããçãã§ããã®ã ãããããã
ã¡ãã£ã¢ãã¯ãããžãŒã©ããšã¢ããã³ã¹ããã¯ãããžãŒã©ã
ãŠã§ãç³»ã®æ°èŠäºæ¥ã¯ããŒã«ãã£ã³ã°ã¹ç®¡èœã®ã¡ãã£ã¢ãã¯ãããžãŒã©ããæ ã£ãŠããããããªã¯ã«ãŒããã¯ãããžãŒãºã¯æ¢åã¡ãã£ã¢ã®ãšã³ãã³ã¹åæ§ç¯ãã¢ããªé åã¯ã¡ã€ã³ã«ãªãããããäŒç€ŸãšããŠæ°èŠäºæ¥ã«åãçµãã®ãé£ããæ§é ã«ãªã£ãŠãããããèªäœã¯æªã§ã¯ãªãããªããªã瀟å¡åèªã¯New Ringãšãã瀟å èµ·æ¥ããã°ã©ã ã«åå ããæ¡æãããã°ã¡ãã£ã¢ãã¯ãããžãŒã©ãã«ç§»ç±ã§ããããã ããŸãããŠããäž»äœæ§ãåãããŠããã
ãŸããæ¬åœã®ã®ãŒã¯ãéãŸã£ãŠãããããã®ãã¢ããã³ã¹ããã¯ãããžãŒã©ãïŒATLïŒã§ãããèªç¶èšèªåŠçãçšããŠããã¬ããšãããããèªåãçŽæ¥ATLã«é¢ãã£ãŠããªãã®ã§ããåãã£ãŠããªãäºå®ã
ãŸãšã
ãªã¯ã«ãŒããã¯ãããžãŒãºã«å¯Ÿããæãèªã£ãã ITäŒæ¥ãšããŠçãŸãå€ããéæž¡æã®è©±ã§ãããåŸã ã«å€åããŠããã®ã ãšæãã ãªã¯ã«ãŒãã°ã«ãŒãITåã®äžæ žãšããŠåããŠã¿ãã人ããããæ¯éäžéæ¡çšã«ç³ã蟌ãã§æ¬²ããã
Qiita API v2 Hackathonã«åå ããŠããïŒåçæ®ã£ãŠQiita Teamã«ã¢ããããŒã
ãã®ãšã³ããªãŒã¯ãæ ªåŒäŒç€Ÿãªã¯ã«ãŒããã¯ãããžãŒãº Advent Calendar 2014ã®17æ¥ç®ã§ãã
2014/12/13ããªã¯ã«ãŒãæ¬ç€ŸãµãŠã¹ã¿ã¯ãŒã§è¡ããã Qiita API v2 Hackathon ã§ãQiitaSnapãªãã¢ããªãäœãçºè¡šãããŠããã ããŸããã
ååã¯ãšãŠã豪è¯ã以äžã®ãšããã
- iPad Air 2
- Kindle Voyage
- Chromebook
çŽ æµãªãµãŠã¹ã¿ã¯ãŒ41éã®æ¯è²ãçžãŸã£ãŠããšãŠã楜ããäŒã§ããã
ïŒãªã¯ã«ãŒããåºãŠããã®ã¯ãããŸã§ã§ãã
Hackathonã®ããŒã
ä»åã®Hackathonã®ããŒãã¯ãQiita APIv2ãå©çšããŠæ¯æ¥ã®éçºã楜ãããªãããŒã«ã®éçºã§ããã ç§ã®ããŒã ã§ã¯Qiita Teamã䜿ã£ãŠãããUIUXèšèšæã®ãã¯ã€ãããŒãäžã®ã¡ã¢ãè°äºé²ãšããŠæçš¿ããããšããããããŸããã ãããæå€ãšé¢åãªã®ã§ãäžç§ã§Qiita Teamäžã«ã¢ããããŒãã§ããiOSã¢ããªãäœããŸããã
ã€ãã£ããã®
UIImagePickerController
ãçšããŠåçãæ®åœ±ããParseã«ç»åãã¢ããããŒãããQiita API v2ã§ç»åãã¢ããããŒãããã·ã³ãã«ãªä»çµã¿ã§ãã
ã«ã¡ã©ã«é¢ããŠã¯UIImagePickerController
ãçšããªãã§ãAVFoundation Frameworkãçšããã°ã«ã¹ã¿ãã€ãºå¯èœãªã«ã¡ã©ãå®è£
ã§ããã®ã§ãããçæéã§ã®å®è£
ã ã£ãããããç°¡åã«å®è£
ã§ããUIImagePickerController
ãçšããŸããã
ãŸããèµ·åçŽåŸã«ã«ã¡ã©ãèµ·åãããã®ç»é¢äžã§æçš¿ããQiita Teamãéžæãããã¿ã³ã衚瀺ã
ã«ã¡ã©ã®éšåã¯ãUIViewControllerã®äžã«ä»¥äžã®ã³ãŒããæžããŠããã
- (void)viewDidLoad { [super viewDidLoad]; // UIImagePickerControllerã®åæèšå® self.picker = [[UIImagePickerController alloc] init]; self.picker.delegate = self; self.picker.allowsEditing = NO; // èµ·åããã®ã¯ã«ã¡ã© self.picker.sourceType = UIImagePickerControllerSourceTypeCamera; // ãã¿ã³ã®èšçœ® UIButton *button = [UIButton buttonWithType:100]; [button setBackgroundImage:[UIImage imageNamed:@"team"] forState:UIControlStateNormal]; [button setFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height - 200, 100, 42)]; [button addTarget:self action:@selector(teamAction:) forControlEvents:UIControlEventTouchUpInside]; self.picker.cameraOverlayView = button; [self presentViewController:_picker animated:YES completion:NULL]; }
ããã§ã«ã¡ã©ã®å®è£ ã¯å®äºã
ã«ã¡ã©ã§æ®åœ±åŸã¯ãUIImagePickerViewControllerDelegate
ã®- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
delegateã¡ãœããããæ®åœ±ç»åãååŸããç»åãµã€ãºãUIGraphicsBeginImageContext
ã«ãŠå€æŽããŠããã
// Resize image UIGraphicsBeginImageContext(CGSizeMake(640, 960)); [image drawInRect: CGRectMake(0, 0, 640, 960)]; UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
ããã«ããçæãããç»åãParseã«ã¢ããããŒãã ãã®ç»åããªã¯ãšã¹ãããURLãååŸããããã«PFFileãªããžã§ã¯ããååŸããã
//PFFileãªããžã§ã¯ããååŸãã PFFile *fileData = [objectData objectForKey:@"imageData"]; //ç»åããŒã¿URLãååŸãã imageURL = fileData.url;
æçµçã«ãã®URLãå ã«POSTããå 容ãçæã ä»åã¯ãæéããªãå¹³æã§ãäžã€ã®Stringã§ä»¥äžã®ããã«ããã
NSString *json = [NSString stringWithFormat:@"{\"body\": \"![](%@)\",\"tags\": [{\"name\": \"QiitaSnap\"}],\"title\": \"è°äºé² %@\",\"tweet\": true}", imageURL, stringFromDate];
ãããQiita API v2ã«ãŠã/api/v2/itemsãšã³ããã€ã³ãã«ã¢ããããŒãããããšä»¥äžã®ããã«æçš¿æçš¿ãããã
ãããã
å€ã«èŠããã圢ã«ããŠããªãªãŒã¹ãããã
ãŸãšã
- Qiita API v2 Hackatonåºãã
- Qiita APIã¯äœ¿ããããã
- ããã«ãœã³ã§äœå䜿ã£ãŠã«ã¡ã©ã¢ããªäœã£ãã
å¿ããªãã§GCDïŒåŸ©ç¿ãããïŒ
ãã®ãšã³ããªãŒã¯ãiOS Advent Calendar 2014 ã® 2æ¥ç®ã§ãã 2æ¥ç®ãªã®ã§ãSwiftãšãã§ã¯ãªãéããã³ããªèšäºã§è¡ããŸãã
éåæåŠçãå€ãæ±ããããã¢ãã€ã«ã¢ããªéçºã®çŸå Žã§ã¯ãReactiveCocoaãRxJavaçã®Frameworkã泚ç®ã济ã³ãŠããã ããããæå€ãšåºæ¬ãšãªãGCD(Grand Central Dispatch)ã®ããšãå¿ããã¡ã
FacebookãšTwitterããã¿ã€ã ã©ã€ã³ãååŸãããå ·åã«è¡šç€ºããæ¡ä»¶ããã£ãŠããæãéåæåŠçãšNSNotificationãå€æ§ããé£è§£ãªå®è£ ãšãªã£ãŠããã ãããdispatch_groupãdispatch_barrier_asyncã䜿ãã°è§£æ±ºã§ãããã ããã ããæ©äŒã ãã埩ç¿ããŠã¿ããã
GCDãšã¯
Dispatch queueã«BlocksãšããŠå®è¡ãããã¿ã¹ã¯ãæž¡ãå®è¡ã§ããããã®queueã«ã¯2çš®é¡ããã
- Serial dispatch queueïŒã¿ã¹ã¯ãé次çã«å®è¡
- Concurrent dispatch queueïŒä»ã®ã¿ã¹ã¯ãåŸ ããã«å®è¡
å®éã«äœ¿ããšãã¯ãæç»ãè¡ãã¡ã€ã³ã¹ã¬ããã§ããMain dispatch queue(Serial dispatch queue)ãšãiOSãããå ·åã«å€æãã¹ã¬ãããäœãå®è¡ããŠãããGlobal dispatch queueã®ã©ã¡ãããéžæããŠäœ¿ãäºã«ãªããGlobal dispatch queueã§ã¯ãåªå 床ãéžã¹ããããã¯ãããŸã§ç®å®ãªã®ã§æ³šæã
Serial dispatch queue
dispatch_queue_t queue = dispatch_queue_create("com.jsk.test", NULL); for (int i = 0; i < 5; i++) { dispatch_async(queue, ^{NSLog(@"%d", i); }); }
Output
0 1 2 3 4
Concurrent dispatch queue
dispatch_queue_t queue = dispatch_queue_create("com.jsk.test", NULL); for (int i = 0; i < 5; i++) { dispatch_async(queue, ^{NSLog(@"%d", i); }); }
Output(é çªã¯å®è¡æã«ãã£ãŠç°ãªã)
4 0 2 1 3
Dispatch Groupã§ã¡ãã£ãšåŸ ã€
Dispatch Groupã䜿ããšãqueueã«è¿œå ããåŠçãã°ã«ãŒãåããå šãŠã®åŠçãå®äºããäºãåãåãäºãã§ããã ããã䜿ãã°ãéåæéä¿¡ãè€æ°èµ°ã£ãŠããå Žåçã®åŠçããŸãšããããšãã§ããŠäŸ¿å©ã 䜿ãæ¹ã¯ãšã£ãŠãç°¡åã
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_t group = dispatch_group_create(); for (int i = 0; i < 3; i++) { dispatch_group_async(group, queue, ^{ NSLog(@"%d", i); }); } dispatch_group_notify(group, queue, ^{ NSLog(@"Done"); });
Output
2 0 1 Done
ãŸããdispatch_group_wait
ãçšããäºã§åŠçããã®ç®æã§æ¢ããäºãã§ããã
Dispatch Barrier Async
äžèšDispatch Groupãšå°ã䌌ãŠããããDispatch barrier asyncã§ã¯ãConcurrent dispatch queueã«è¿œå ãããåŠçãå®è¡å®äºããããŸã§åŸ ã¡ãSerial Dispatch Queueã«æ°ããªã¿ã¹ã¯ãè¿œå ãããã®ã¿ã¹ã¯ãå®è¡å®äºããããŸã§åŸ ã€ããšãå¯èœã ã äŸãã°ä»¥äžã®ããã«äœ¿ãããšãã§ããã
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{NSLog(@"1");}); dispatch_async(queue, ^{NSLog(@"2");}); dispatch_async(queue, ^{NSLog(@"3");}); dispatch_barrier_async(queue, ^{NSLog(@"wait");}); dispatch_async(queue, ^{NSLog(@"4");}); dispatch_async(queue, ^{NSLog(@"5");});
dispatch_barrier_asyncã¡ãœããã䜿ãã ãã§ãåã®åŠçãåŸ ã£ãŠãããããªããŠäŸ¿å©ãªãã ã
ãŸãšã
GCDã埩ç¿ããã dispatch_groupãdispatch_barrier_asyncãçšããŠä»ã®éåæåŠçãåŸ ã€äºãã§ããã ããã§semaphoreã§ç¡çããåŠçããŠããç®æãæžãæããäºãã§ãããã ã
ããŸã
Rebuild.fmã§çŽ¹ä»ãããŠããHBOã®Silicon ValleyãèŠãŠããããã®è¿èŸºã§ã®ã¹ã¿ãŒãã¢ããããªã¢ã«ã«æãããŠããŠããªãé¢çœããããããã ã
iOSã®ãç»é¢é·ç§»æã®ã¡ã¢ãªãªãŒã¯ãæ¢ãŸããªãã£ã話
å
æ¥ãç»é¢é·ç§»æã«ã¡ã¢ãªãéæŸããããåŸã
ã«ã¡ã¢ãªå©çšçãäžæããçŸè±¡ã«èŠããŸãããã
Instrumentsã§èª¿ã¹ãŠã¿ãŠãããªãŒã¯ã¯èŠãããªãã£ããäœãåé¡ã ã£ãã®ããããã¯dispatch_after
ãçšããã«ãŒãããã¢ãã¡ãŒã·ã§ã³ã ã£ãã
dispatch_after
ããNSRunLoop
ãNSTimer
çãçšããŠã«ãŒãåŠçãå®è¡ããŠãããšãownerãšãªããªããžã§ã¯ãã解æŸãããããšããŠãããããã®ãªããžã§ã¯ãã匷åç
§ããããã«ã解æŸãããªãããã ã
ä»åå®è£ ããŠããç©
UIImageView
ã®ã«ã¹ã¿ã ã¯ã©ã¹ã®äžã«ãUIImage
ãä¹ã£ãŠãããanimationImages
ãšNSTimer
ã«ãã£ãŠããã§ãŒãã€ã³ã»ã¢ãŠãããã¢ãã¡ãŒã·ã§ã³ã®æåãå®è£
ããã
åèïŒiphone fading of images
å ã ã®å®è£
ããã ãšãã«ãŒããåãç¶ããownerã®ãªããžã§ã¯ãã¯æ°žé ã«éæŸãããªã
NSTimer *timer = [NSTimer timerWithTimeInterval:4.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; [timer fire];
察çåŸ
NSTimerãpropertyãšããŠæã¡ãViewãæ¶ããæã«ãinvalidate
ãã解æŸããå¿
èŠãããã
@interface JSKSwipeViewController () @property (nonatomic) NSTimer *timer; @end @implementation JSKSwipeViewController - (void)startAnimation { _timer = [NSTimer timerWithTimeInterval:4.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; // stop animation and release [self.timer invalidate]; self.timer = nil; }
UINavigationControllerã®æ»ããæ¶ããå¥ã®ãã¿ã³ã§æ»ã
ViewDidLoadã«ãŠä»¥äžã®ã¡ãœãããåŒã¶ã UINavigationControlleräžã®æ»ããã¿ã³ãæ¶ããã
[self.navigationItem setHidesBackButton:YES];
察象ãšãªãIBActionå ã§ä»¥äžãåŒã¶ã
[self.navigationController popViewControllerAnimated:YES];
çµæã以äžã®ããã«ã