Sunday, July 20, 2014

Videos from youtube channel in iOS app (part 2)

We want to display list of channel's uploads. That list has an identifier, we need to find out, and it can be done with this request:
1. Channel details.

- (void) channelDetails {
   GTLServiceYouTube *service = [[GTLServiceYouTube alloc] init];
   service.APIKey = API_KEY;
   GTLQueryYouTube *query = [GTLQueryYouTube queryForChannelsListWithPart:@"contentDetails"];
   query.forUsername = CHANNEL_NAME;
   [service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
      if (!error) {
          GTLYouTubeChannelListResponse *items = object;
          for (GTLYouTubeChannelListResponse * item in items){
             NSLog(@"item: %@", item.JSON[@"contentDetails"]); 
          }
      } else{
           NSLog(@"%@", error);
      }
   }];
}


Response is in this format:

item: {
   googlePlusUserId = XXXXXXXXXX;
   relatedPlaylists = {
       uploads = "YYYYYYYYYYYYY";
   };
}

Store the value from "uploads" field to UPLOADS_LIST_ID.

2. List of uploaded videos. To receive list of uploaded videos we need to make a playlist items query with UPLOADS_LIST_ID as playlist id.


- (void) getUploads {
   GTLServiceYouTube *service = [[GTLServiceYouTube alloc] init];   service.APIKey = API_KEY;
   GTLQueryYouTube *query = [GTLQueryYouTube queryForPlaylistItemsListWithPart:@"id,snippet"];
   query.playlistId = UPLOADS_LIST_ID;
   query.maxResults = MAX_RESULTS; 
   [service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
      if (!error) {
         GTLYouTubePlaylistItemListResponse *playlistItems = object;
         for (GTLYouTubePlaylistItem *playlistItem in playlistItems) {
            [self.identifiers addObject:playlistItem.snippet.resourceId.JSON[@"videoId"]];
         }
      [self getVideos];
     }else {
      NSLog(@"%@", error);
     }
   }];
}

3. List of uploaded videos with all information. Playlist queries, like one from above give us list of videos with details like: video id, title and thumbnail. To be able to read information like video duration and number of views, we need to make video list query. We can use list of video identifiers as filter for that query. For that reason we stored them in self.identifiers property of NSMutableDictionary type.

- (void) getVideos {
   GTLServiceYouTube *service = [[GTLServiceYouTube alloc] init];
   service.APIKey = API_KEY;
   GTLQueryYouTube *query = [GTLQueryYouTube queryForVideosListWithPart:@"id, snippet, contentDetails, statistics, player"];
   query.identifier = [[self.identifiers valueForKey:@"description"] componentsJoinedByString:@","];
   [service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error){
      if (!error) {
         GTLYouTubeVideoListResponse *videolistItems = object;
         for (GTLYouTubeVideo *videoItem in videolistItems){
            [self.dataSource addObject:videoItem];
         }
         [self.tableView reloadData]; 
      } else {
      NSLog(@"%@", error);
      }
   }];
}

You may also need query for list of playlists for fetching all information from one channel. For this query we will need CHANNEL_ID, not name.
4. List of channel's playlists:

- (void) loadPlaylists {
   GTLServiceYouTube *service = [[GTLServiceYouTube alloc] init];
   service.APIKey = API_KEY;
   GTLQueryYouTube *query = [GTLQueryYouTube queryForPlaylistsListWithPart:@"id, snippet, contentDetails"];
   query.channelId = CHANNEL_ID;
   query.maxResults = MAX_RESULTS;
   [service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
      if (!error) {
         GTLYouTubePlaylistListResponse *items = object;
         for (GTLYouTubePlaylist * item in items) {
            [self.dataSource addObject:item];
         }
         [self.tableView reloadData];
      } else {
         NSLog(@"%@", error);
      }
   }];
}