Cast'i iOS Uygulamanıza Entegre Edin

Bu geliştirici kılavuzunda, iOS Sender SDK'sını kullanarak iOS gönderen uygulamanıza Google Cast desteğini nasıl ekleyeceğiniz açıklanmaktadır.

Mobil cihaz veya dizüstü bilgisayar, oynatmayı kontrol eden gönderen, Google Cast cihazı ise içeriği TV'de görüntüleyen alıcıdır.

Gönderen çerçevesi, göndericinin çalışma zamanında mevcut olan Cast sınıfı kitaplığı ikili programını ve ilişkili kaynakları ifade eder. Gönderen uygulaması veya Cast uygulaması, gönderende de çalışan bir uygulamayı belirtir. Web Alıcısı uygulaması, Web Alıcısı'nda çalışan HTML uygulamasını belirtir.

Gönderen çerçevesi, gönderen uygulamayı etkinlikler hakkında bilgilendirmek ve Cast uygulamasının yaşam döngüsünün çeşitli durumları arasında geçiş yapmak için eşzamansız bir geri çağırma tasarımı kullanır.

Uygulama akışı

Aşağıdaki adımlarda, bir gönderen iOS uygulaması için tipik üst düzey yürütme akışı açıklanmaktadır:

  • Cast çerçevesi, cihazları taramaya başlamak için GCKCastOptions içinde sağlanan özelliklere göre GCKDiscoveryManager tarihinde başlar.
  • Kullanıcı Yayınla düğmesini tıkladığında çerçeve, keşfedilen Yayın cihazlarının listesini içeren Yayınla iletişim kutusunu gösterir.
  • Kullanıcı bir Yayın cihazı seçtiğinde, çerçeve Yayın cihazında Web Alıcısı uygulamasını başlatmayı dener.
  • Çerçeve, Web Alıcısı uygulamasının başlatıldığını onaylamak için gönderen uygulamada geri çağırmaları çağırır.
  • Çerçeve, gönderen ve Web Alıcı uygulamaları arasında bir iletişim kanalı oluşturur.
  • Çerçeve, Web Alıcısı'na medya içeriği oynatmak ve oynatmak için iletişim kanalını kullanır.
  • Çerçeve, gönderen ve Web Alıcı arasında medya oynatma durumunu senkronize eder: Kullanıcı, gönderen kullanıcı arayüzü işlemleri yaptığında, çerçeve bu medya denetimi isteklerini Web Alıcısına iletir ve Web Alıcısı medya durumu güncellemelerini gönderdiğinde çerçeve, gönderenin kullanıcı arayüzünün durumunu günceller.
  • Kullanıcı, Yayın cihazıyla olan bağlantıyı kesmek için Yayınla düğmesini tıkladığında çerçeve, gönderen uygulamanın Web Alıcısı ile bağlantısını keser.

Göndereninizle ilgili sorunları gidermek için günlük kaydını etkinleştirmeniz gerekir.

Google Cast iOS çerçevesindeki tüm sınıfların, yöntemlerin ve etkinliklerin kapsamlı bir listesi için Google Cast iOS API Referansı'na bakın. Aşağıdaki bölümlerde Cast'i iOS uygulamanıza entegre etme adımları ele alınmaktadır.

Ana ileti dizisinden arama yöntemleri

Yayınlama bağlamını başlatma

Cast çerçevesi, çerçevenin tüm etkinliklerini koordine eden global bir tekil nesne olan GCKCastContextdan oluşur. Gönderen uygulaması yeniden başlatıldığında otomatik oturum devam ettirmenin düzgün bir şekilde tetiklenebilmesi için bu nesnenin, uygulamanın yaşam döngüsünün başlarında, genellikle uygulama yetkisinin -[application:didFinishLaunchingWithOptions:] yöntemiyle başlatılması gerekir.

GCKCastContext başlatılırken bir GCKCastOptions nesnesi sağlanmalıdır. Bu sınıf, çerçevenin davranışını etkileyen seçenekler içerir. Bunların en önemlisi, keşif sonuçlarını filtrelemek ve bir Yayın oturumu başlatıldığında Web Alıcısı uygulamasını başlatmak için kullanılan Web Alıcısı uygulama kimliğidir.

-[application:didFinishLaunchingWithOptions:] yöntemi, çerçeveden günlük kaydı mesajlarını almak amacıyla günlük kaydı temsilcisi ayarlamak için de iyi bir yerdir. Bunlar hata ayıklama ve sorun giderme için yararlı olabilir.

Hızlıca
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GCKLoggerDelegate {
  let kReceiverAppID = kGCKDefaultMediaReceiverApplicationID
  let kDebugLoggingEnabled = true

  var window: UIWindow?

  func applicationDidFinishLaunching(_ application: UIApplication) {
    let criteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID)
    let options = GCKCastOptions(discoveryCriteria: criteria)
    GCKCastContext.setSharedInstanceWith(options)

    // Enable logger.
    GCKLogger.sharedInstance().delegate = self

    ...
  }

  // MARK: - GCKLoggerDelegate

  func logMessage(_ message: String,
                  at level: GCKLoggerLevel,
                  fromFunction function: String,
                  location: String) {
    if (kDebugLoggingEnabled) {
      print(function + " - " + message)
    }
  }
}
Objective-C

AppDelegate.h

@interface AppDelegate () <GCKLoggerDelegate>
@end

AppDelegate.m

@implementation AppDelegate

static NSString *const kReceiverAppID = @"AABBCCDD";
static const BOOL kDebugLoggingEnabled = YES;

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  GCKDiscoveryCriteria *criteria = [[GCKDiscoveryCriteria alloc]
                                    initWithApplicationID:kReceiverAppID];
  GCKCastOptions *options = [[GCKCastOptions alloc] initWithDiscoveryCriteria:criteria];
  [GCKCastContext setSharedInstanceWithOptions:options];

  // Enable logger.
  [GCKLogger sharedInstance].delegate = self;

  ...

  return YES;
}

...

#pragma mark - GCKLoggerDelegate

- (void)logMessage:(NSString *)message
           atLevel:(GCKLoggerLevel)level
      fromFunction:(NSString *)function
          location:(NSString *)location {
  if (kDebugLoggingEnabled) {
    NSLog(@"%@ - %@, %@", function, message, location);
  }
}

@end

Cast kullanıcı deneyimi widget'ları

Cast iOS SDK'sı, Yayın Tasarım Kontrol Listesi'ne uygun şu widget'ları sağlar:

  • Tanıtım Yer Paylaşımı: GCKCastContext sınıfında, bir Web Alıcısı ilk kez kullanılabilir olduğunda Yayın düğmesini öne çıkarmak için kullanılabilecek bir presentCastInstructionsViewControllerOnceWithCastButton yöntemi bulunur. Gönderen uygulaması metni, başlık metninin konumunu ve Kapat düğmesini özelleştirebilir.

  • Yayınla Düğmesi: Yayınla iOS gönderen SDK 4.6.0 sürümünden itibaren, gönderen cihaz kablosuz ağa bağlandığında yayınlama düğmesi her zaman görünür durumdadır. Kullanıcı uygulamayı ilk başlattıktan sonra Yayınla düğmesine ilk kez dokunduğunda, uygulamanın ağdaki cihazlara yerel ağ erişimine izin verebilmesi için bir izinler iletişim kutusu görüntülenir. Ardından, kullanıcı yayın düğmesine dokunduğunda, keşfedilen cihazları listeleyen bir yayınlama iletişim kutusu gösterilir. Cihaz bağlıyken kullanıcı yayın düğmesine dokunduğunda, mevcut medya meta verileri (başlık, kayıt stüdyosunun adı ve küçük resim gibi) görüntülenir veya kullanıcının yayın cihazıyla bağlantısını kesmesine olanak tanır. Kullanıcı, kullanılabilir cihaz yokken yayın düğmesine dokunduğunda, kullanıcıya cihazların neden bulunamadığı ve nasıl sorun giderileceği hakkında bilgi veren bir ekran gösterilir.

  • Mini Denetleyici: Kullanıcı içerik yayınlarken mevcut içerik sayfasından veya genişletilmiş denetleyiciden gönderen uygulamasında başka bir ekrana gittiğinde mini denetleyici, kullanıcının yayınlanan medya meta verilerini görmesine ve oynatmayı kontrol etmesine olanak tanımak için ekranın alt kısmında görüntülenir.

  • Genişletilmiş Denetleyici: Kullanıcı içerik yayınlarken medya bildirimini veya mini denetleyiciyi tıklarsa genişletilmiş kumanda başlatılır. Bu kontrol, şu anda oynatılan medya meta verilerini görüntüler ve medya oynatmayı kontrol etmek için çeşitli düğmeler sağlar.

Yayınla düğmesi ekle

Çerçeve, UIButton alt sınıfı olarak bir Yayınla düğmesi bileşeni sağlar. UIBarButtonItem içine sarmalanarak uygulamanın başlık çubuğuna eklenebilir. Tipik bir UIViewController alt sınıfı aşağıdaki şekilde bir Yayınla düğmesi yükleyebilir:

Hızlıca
let castButton = GCKUICastButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24))
castButton.tintColor = UIColor.gray
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: castButton)
Objective-C
GCKUICastButton *castButton = [[GCKUICastButton alloc] initWithFrame:CGRectMake(0, 0, 24, 24)];
castButton.tintColor = [UIColor grayColor];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:castButton];

Varsayılan olarak, düğmeye dokunduğunuzda çerçeve tarafından sağlanan Yayınla iletişim kutusu açılır.

GCKUICastButton doğrudan film şeridine de eklenebilir.

Cihaz bulmayı yapılandırma

Bu çerçevede cihaz keşfi otomatik olarak gerçekleşir. Özel bir kullanıcı arayüzü uygulamadığınız sürece keşif sürecini açıkça başlatmanıza veya durdurmanıza gerek yoktur.

Çerçevedeki keşif, GCKCastContext öğesinin bir özelliği olan GCKDiscoveryManager sınıfı tarafından yönetilir. Çerçeve, cihaz seçimi ve kontrolü için varsayılan bir Cast iletişim kutusu bileşeni sağlar. Cihaz listesi, sözlükte cihaz dostu ada göre sıralanır.

Oturum yönetiminin işleyiş şekli

Cast SDK'sı bir cihaza bağlanma, bir Web Alıcısı uygulamasını başlatma (veya katılma), uygulamaya bağlanma ve bir medya kontrol kanalını başlatma adımlarını birleştiren Cast oturumu kavramını tanıtmaktadır. Yayın oturumları ve Web Alıcısı yaşam döngüsü hakkında daha fazla bilgi için Web Alıcısı Uygulama yaşam döngüsü kılavuzuna bakın.

Oturumlar, GCKCastContext mülkünün bir özelliği olan GCKSessionManager sınıfı tarafından yönetilir. Bağımsız oturumlar GCKSession sınıfının alt sınıflarıyla temsil edilir: Örneğin, GCKCastSession Cast cihazlarıyla oturumları temsil eder. Şu anda etkin olan Yayınlama oturumuna (varsa) GCKSessionManager öğesinin currentCastSession özelliği olarak erişebilirsiniz.

GCKSessionManagerListener arayüzü; oturum oluşturma, askıya alma, devam ettirme ve sonlandırma gibi oturum etkinliklerini izlemek için kullanılabilir. Çerçeve, gönderen uygulaması arka plana geçerken oturumları otomatik olarak askıya alır ve uygulama ön plana döndüğünde (veya oturum etkinken uygulama anormal/ani bir sonlandırıldıktan sonra yeniden başlatıldığında) oturum devam ettirilir.

Yayınlama iletişim kutusu kullanılıyorsa oturumlar oluşturulur ve kullanıcı hareketlerine yanıt olarak otomatik olarak feshedilir. Aksi takdirde, uygulama, GCKSessionManager üzerindeki yöntemler aracılığıyla oturumları açıkça başlatabilir ve sonlandırabilir.

Uygulamanın, oturum yaşam döngüsü olaylarına yanıt olarak özel işlemler yapması gerekiyorsa GCKSessionManager ile bir veya daha fazla GCKSessionManagerListener örneği kaydedebilir. GCKSessionManagerListener; oturum başlangıcı, oturum sonu vb. etkinlikler için geri çağırmaları tanımlayan bir protokoldür.

Akış aktarımı

Oturum durumunun korunması, akış aktarımının temelini oluşturur. Burada kullanıcılar, mevcut ses ve video akışlarını sesli komutlar, Google Home uygulaması veya akıllı ekranlar kullanarak cihazlar arasında taşıyabilir. Medyanın oynatılması bir cihazda (kaynak) durdurulur ve başka bir cihazda (hedef) devam eder. En yeni donanım yazılımına sahip her yayın cihazı, akış aktarımında kaynak veya hedef olarak kullanılabilir.

Akış aktarımı sırasında yeni hedef cihazı almak için [sessionManager:didResumeCastSession:] geri çağırma işlemi sırasında GCKCastSession#device özelliğini kullanın.

Daha fazla bilgi için Web Alıcısı'nda akış aktarımı bölümüne bakın.

Otomatik yeniden bağlanma

Cast çerçevesi, aşağıdaki gibi pek çok rastlanmayan durumda yeniden bağlantıyı otomatik olarak halletmek için yeniden bağlantı mantığı ekler:

  • Geçici kablosuz ağ kaybından kurtarma
  • Cihaz uyku modundan çık
  • Uygulamayı arka plana alarak kurtarma
  • Uygulama çöktüyse kurtarma

Medya denetimi nasıl çalışır?

Medya ad alanını destekleyen bir Web Alıcısı uygulamasıyla bir Cast oturumu oluşturulursa çerçeve tarafından otomatik olarak GCKRemoteMediaClient örneği oluşturulur. Bu örneğe GCKCastSession örneğinin remoteMediaClient özelliği olarak erişilebilir.

GCKRemoteMediaClient üzerinde Web Alıcısına istekte bulunan tüm yöntemler, bu isteği izlemek için kullanılabilecek bir GCKRequest nesnesi döndürür. İşlemin nihai sonucu hakkında bildirim almak için bu nesneye bir GCKRequestDelegate atanabilir.

GCKRemoteMediaClient örneğinin uygulamanın birden fazla bölümü tarafından paylaşılması beklenir. Hatta Cast iletişim kutusu ve mini medya kontrolleri gibi çerçevenin bazı dahili bileşenleri de örneği paylaşır. Bu amaçla GCKRemoteMediaClient, birden fazla GCKRemoteMediaClientListener kaydını destekler.

Medya meta verilerini ayarla

GCKMediaMetadata sınıfı, yayınlamak istediğiniz bir medya öğesiyle ilgili bilgileri temsil eder. Aşağıdaki örnek, bir filmin yeni GCKMediaMetadata örneğini oluşturur ve başlığı, altyazıyı, kayıt stüdyosunun adını ve iki resmi ayarlar.

Hızlıca
let metadata = GCKMediaMetadata()
metadata.setString("Big Buck Bunny (2008)", forKey: kGCKMetadataKeyTitle)
metadata.setString("Big Buck Bunny tells the story of a giant rabbit with a heart bigger than " +
  "himself. When one sunny day three rodents rudely harass him, something " +
  "snaps... and the rabbit ain't no bunny anymore! In the typical cartoon " +
  "tradition he prepares the nasty rodents a comical revenge.",
                   forKey: kGCKMetadataKeySubtitle)
metadata.addImage(GCKImage(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg")!,
                           width: 480,
                           height: 360))
Objective-C
GCKMediaMetadata *metadata = [[GCKMediaMetadata alloc]
                                initWithMetadataType:GCKMediaMetadataTypeMovie];
[metadata setString:@"Big Buck Bunny (2008)" forKey:kGCKMetadataKeyTitle];
[metadata setString:@"Big Buck Bunny tells the story of a giant rabbit with a heart bigger than "
 "himself. When one sunny day three rodents rudely harass him, something "
 "snaps... and the rabbit ain't no bunny anymore! In the typical cartoon "
 "tradition he prepares the nasty rodents a comical revenge."
             forKey:kGCKMetadataKeySubtitle];
[metadata addImage:[[GCKImage alloc]
                    initWithURL:[[NSURL alloc] initWithString:@"https://commondatastorage.googleapis.com/"
                                 "gtv-videos-bucket/sample/images/BigBuckBunny.jpg"]
                    width:480
                    height:360]];

Görüntülerin medya meta verileriyle kullanımıyla ilgili Resim Seçimi ve Önbelleğe Alma bölümüne bakın.

Medya yükle

Bir medya öğesi yüklemek için medyanın meta verilerini kullanarak bir GCKMediaInformation örneği oluşturun. Ardından, mevcut GCKCastSession paketini edinin ve medyayı alıcı uygulamaya yüklemek için GCKRemoteMediaClient aracını kullanın. Ardından, alıcıda çalışan oynatma, duraklatma ve durdurma gibi bir medya oynatıcı uygulamasını kontrol etmek için GCKRemoteMediaClient kullanabilirsiniz.

Hızlıca
let url = URL.init(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
guard let mediaURL = url else {
  print("invalid mediaURL")
  return
}

let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentURL: mediaURL)
mediaInfoBuilder.streamType = GCKMediaStreamType.none;
mediaInfoBuilder.contentType = "video/mp4"
mediaInfoBuilder.metadata = metadata;
mediaInformation = mediaInfoBuilder.build()

guard let mediaInfo = mediaInformation else {
  print("invalid mediaInformation")
  return
}

if let request = sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInfo) {
  request.delegate = self
}
Objective-C
GCKMediaInformationBuilder *mediaInfoBuilder =
  [[GCKMediaInformationBuilder alloc] initWithContentURL:
   [NSURL URLWithString:@"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"]];
mediaInfoBuilder.streamType = GCKMediaStreamTypeNone;
mediaInfoBuilder.contentType = @"video/mp4";
mediaInfoBuilder.metadata = metadata;
self.mediaInformation = [mediaInfoBuilder build];

GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMedia:self.mediaInformation];
if (request != nil) {
  request.delegate = self;
}

Ayrıca, medya kanallarını kullanma ile ilgili bölüme de bakın.

4K video biçimi

Medyanızın hangi video biçimini kullandığını belirlemek için GCKMediaStatus öğesinin videoInfo özelliğini kullanarak GCKVideoInfo öğesinin geçerli örneğini alın. Bu örnekte, HDR TV biçimi türü ile yükseklik ve genişliği piksel cinsinden belirtilmiştir. 4K biçiminin varyantları, hdrType özelliğinde GCKVideoInfoHDRType enum değerleriyle belirtilir.

Mini kumanda ekleyin

Yayın Tasarım Kontrol Listesi'ne göre, gönderen bir uygulama, kullanıcı geçerli içerik sayfasından ayrıldığında görünmesi gereken mini denetleyici olarak bilinen kalıcı bir kontrol sağlamalıdır. Mini kumanda, geçerli Yayın oturumu için anında erişim ve görünür bir hatırlatıcı sağlar.

Cast çerçevesi, mini kumandayı göstermek istediğiniz sahnelere eklenebilen bir kontrol çubuğu (GCKUIMiniMediaControlsViewController) sağlar.

Gönderen uygulamanız video veya işitsel canlı yayın oynatırken SDK, mini kumandadaki oynat/duraklat düğmesinin yerine otomatik olarak bir oynat/durdur düğmesi görüntüler.

Gönderen uygulamanızın, Yayın widget'larının görünümünü nasıl yapılandırabileceğini öğrenmek için iOS Gönderen Kullanıcı Arayüzünü Özelleştirme bölümüne bakın.

Mini kumandayı gönderen uygulamasına iki şekilde ekleyebilirsiniz:

  • Mevcut görünüm denetleyicinizi kendi görünüm denetleyicisiyle sarmalayarak Cast çerçevesinin mini denetleyicinin düzenini yönetmesine izin verin.
  • Mini kumanda widget'ının düzenini film şeridine alt görünüm sağlayarak mevcut görünüm denetleyicinize ekleyerek kendiniz yönetebilirsiniz.

GCKUICastContainerViewController kullanarak sarmalama

İlk yöntem, başka bir görünüm denetleyicisini sarmalayan ve alt kısma bir GCKUIMiniMediaControlsViewController ekleyen GCKUICastContainerViewController öğesini kullanmaktır. Bu yaklaşım, animasyonu özelleştiremeyeceğiniz ve kapsayıcı görünümü denetleyicisinin davranışını yapılandıramayacağınız için sınırlıdır.

Bu ilk yöntem genellikle uygulama temsilcisinin -[application:didFinishLaunchingWithOptions:] yöntemiyle yapılır:

Hızlıca
func applicationDidFinishLaunching(_ application: UIApplication) {
  ...

  // Wrap main view in the GCKUICastContainerViewController and display the mini controller.
  let appStoryboard = UIStoryboard(name: "Main", bundle: nil)
  let navigationController = appStoryboard.instantiateViewController(withIdentifier: "MainNavigation")
  let castContainerVC =
          GCKCastContext.sharedInstance().createCastContainerController(for: navigationController)
  castContainerVC.miniMediaControlsItemEnabled = true
  window = UIWindow(frame: UIScreen.main.bounds)
  window!.rootViewController = castContainerVC
  window!.makeKeyAndVisible()

  ...
}
Objective-C
- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  ...

  // Wrap main view in the GCKUICastContainerViewController and display the mini controller.
  UIStoryboard *appStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
  UINavigationController *navigationController =
          [appStoryboard instantiateViewControllerWithIdentifier:@"MainNavigation"];
  GCKUICastContainerViewController *castContainerVC =
          [[GCKCastContext sharedInstance] createCastContainerControllerForViewController:navigationController];
  castContainerVC.miniMediaControlsItemEnabled = YES;
  self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
  self.window.rootViewController = castContainerVC;
  [self.window makeKeyAndVisible];
  ...

}
Swift
var castControlBarsEnabled: Bool {
  set(enabled) {
    if let castContainerVC = self.window?.rootViewController as? GCKUICastContainerViewController {
      castContainerVC.miniMediaControlsItemEnabled = enabled
    } else {
      print("GCKUICastContainerViewController is not correctly configured")
    }
  }
  get {
    if let castContainerVC = self.window?.rootViewController as? GCKUICastContainerViewController {
      return castContainerVC.miniMediaControlsItemEnabled
    } else {
      print("GCKUICastContainerViewController is not correctly configured")
      return false
    }
  }
}
Objective-C

AppDelegate.h

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, assign) BOOL castControlBarsEnabled;

@end

AppDelegate.m

@implementation AppDelegate

...

- (void)setCastControlBarsEnabled:(BOOL)notificationsEnabled {
  GCKUICastContainerViewController *castContainerVC;
  castContainerVC =
      (GCKUICastContainerViewController *)self.window.rootViewController;
  castContainerVC.miniMediaControlsItemEnabled = notificationsEnabled;
}

- (BOOL)castControlBarsEnabled {
  GCKUICastContainerViewController *castContainerVC;
  castContainerVC =
      (GCKUICastContainerViewController *)self.window.rootViewController;
  return castContainerVC.miniMediaControlsItemEnabled;
}

...

@end

Mevcut görünüm denetleyicisine yerleştir

İkinci yöntem, GCKUIMiniMediaControlsViewController örneği oluşturmak için createMiniMediaControlsViewController kullanarak ve ardından alt görünüm olarak container görünümü denetleyicisine ekleyerek mini denetleyiciyi doğrudan mevcut görünüm denetleyicinize eklemektir.

Uygulama yetkilendirmesinde görünüm denetleyicinizi ayarlayın:

Hızlıca
func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  ...

  GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true
  window?.clipsToBounds = true

  let rootContainerVC = (window?.rootViewController as? RootContainerViewController)
  rootContainerVC?.miniMediaControlsViewEnabled = true

  ...

  return true
}
Objective-C
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  ...

  [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = YES;

  self.window.clipsToBounds = YES;

  RootContainerViewController *rootContainerVC;
  rootContainerVC =
      (RootContainerViewController *)self.window.rootViewController;
  rootContainerVC.miniMediaControlsViewEnabled = YES;

  ...

  return YES;
}

Kök görünümü denetleyicinizde bir GCKUIMiniMediaControlsViewController örneği oluşturun ve bunu alt görünüm olarak kapsayıcı görünümü denetleyicisine ekleyin:

Hızlıca
let kCastControlBarsAnimationDuration: TimeInterval = 0.20

@objc(RootContainerViewController)
class RootContainerViewController: UIViewController, GCKUIMiniMediaControlsViewControllerDelegate {
  @IBOutlet weak private var _miniMediaControlsContainerView: UIView!
  @IBOutlet weak private var _miniMediaControlsHeightConstraint: NSLayoutConstraint!
  private var miniMediaControlsViewController: GCKUIMiniMediaControlsViewController!
  var miniMediaControlsViewEnabled = false {
    didSet {
      if self.isViewLoaded {
        self.updateControlBarsVisibility()
      }
    }
  }

  var overriddenNavigationController: UINavigationController?

  override var navigationController: UINavigationController? {

    get {
      return overriddenNavigationController
    }

    set {
      overriddenNavigationController = newValue
    }
  }
  var miniMediaControlsItemEnabled = false

  override func viewDidLoad() {
    super.viewDidLoad()
    let castContext = GCKCastContext.sharedInstance()
    self.miniMediaControlsViewController = castContext.createMiniMediaControlsViewController()
    self.miniMediaControlsViewController.delegate = self
    self.updateControlBarsVisibility()
    self.installViewController(self.miniMediaControlsViewController,
                               inContainerView: self._miniMediaControlsContainerView)
  }

  func updateControlBarsVisibility() {
    if self.miniMediaControlsViewEnabled && self.miniMediaControlsViewController.active {
      self._miniMediaControlsHeightConstraint.constant = self.miniMediaControlsViewController.minHeight
      self.view.bringSubview(toFront: self._miniMediaControlsContainerView)
    } else {
      self._miniMediaControlsHeightConstraint.constant = 0
    }
    UIView.animate(withDuration: kCastControlBarsAnimationDuration, animations: {() -> Void in
      self.view.layoutIfNeeded()
    })
    self.view.setNeedsLayout()
  }

  func installViewController(_ viewController: UIViewController?, inContainerView containerView: UIView) {
    if let viewController = viewController {
      self.addChildViewController(viewController)
      viewController.view.frame = containerView.bounds
      containerView.addSubview(viewController.view)
      viewController.didMove(toParentViewController: self)
    }
  }

  func uninstallViewController(_ viewController: UIViewController) {
    viewController.willMove(toParentViewController: nil)
    viewController.view.removeFromSuperview()
    viewController.removeFromParentViewController()
  }

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "NavigationVCEmbedSegue" {
      self.navigationController = (segue.destination as? UINavigationController)
    }
  }

...
Objective-C

RootContainerViewController.h

static const NSTimeInterval kCastControlBarsAnimationDuration = 0.20;

@interface RootContainerViewController () <GCKUIMiniMediaControlsViewControllerDelegate> {
  __weak IBOutlet UIView *_miniMediaControlsContainerView;
  __weak IBOutlet NSLayoutConstraint *_miniMediaControlsHeightConstraint;
  GCKUIMiniMediaControlsViewController *_miniMediaControlsViewController;
}

@property(nonatomic, weak, readwrite) UINavigationController *navigationController;

@property(nonatomic, assign, readwrite) BOOL miniMediaControlsViewEnabled;
@property(nonatomic, assign, readwrite) BOOL miniMediaControlsItemEnabled;

@end

RootContainerViewController.m

@implementation RootContainerViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  GCKCastContext *castContext = [GCKCastContext sharedInstance];
  _miniMediaControlsViewController =
      [castContext createMiniMediaControlsViewController];
  _miniMediaControlsViewController.delegate = self;

  [self updateControlBarsVisibility];
  [self installViewController:_miniMediaControlsViewController
              inContainerView:_miniMediaControlsContainerView];
}

- (void)setMiniMediaControlsViewEnabled:(BOOL)miniMediaControlsViewEnabled {
  _miniMediaControlsViewEnabled = miniMediaControlsViewEnabled;
  if (self.isViewLoaded) {
    [self updateControlBarsVisibility];
  }
}

- (void)updateControlBarsVisibility {
  if (self.miniMediaControlsViewEnabled &&
      _miniMediaControlsViewController.active) {
    _miniMediaControlsHeightConstraint.constant =
        _miniMediaControlsViewController.minHeight;
    [self.view bringSubviewToFront:_miniMediaControlsContainerView];
  } else {
    _miniMediaControlsHeightConstraint.constant = 0;
  }
  [UIView animateWithDuration:kCastControlBarsAnimationDuration
                   animations:^{
                     [self.view layoutIfNeeded];
                   }];
  [self.view setNeedsLayout];
}

- (void)installViewController:(UIViewController *)viewController
              inContainerView:(UIView *)containerView {
  if (viewController) {
    [self addChildViewController:viewController];
    viewController.view.frame = containerView.bounds;
    [containerView addSubview:viewController.view];
    [viewController didMoveToParentViewController:self];
  }
}

- (void)uninstallViewController:(UIViewController *)viewController {
  [viewController willMoveToParentViewController:nil];
  [viewController.view removeFromSuperview];
  [viewController removeFromParentViewController];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  if ([segue.identifier isEqualToString:@"NavigationVCEmbedSegue"]) {
    self.navigationController =
        (UINavigationController *)segue.destinationViewController;
  }
}

...

@end

GCKUIMiniMediaControlsViewControllerDelegate, mini kumandanın ne zaman görünmesi gerektiğini ana makine görünümü denetleyicisine bildirir:

Hızlıca
  func miniMediaControlsViewController(_: GCKUIMiniMediaControlsViewController,
                                       shouldAppear _: Bool) {
    updateControlBarsVisibility()
  }
Objective-C
- (void)miniMediaControlsViewController:
            (GCKUIMiniMediaControlsViewController *)miniMediaControlsViewController
                           shouldAppear:(BOOL)shouldAppear {
  [self updateControlBarsVisibility];
}

Genişletilmiş denetleyici ekle

Google Cast Tasarım Kontrol Listesi, gönderen uygulamanın, yayınlanan medya için genişletilmiş bir denetleyici sağlamasını gerektirir. Genişletilmiş kumanda, mini kumandanın tam ekran sürümüdür.

Genişletilmiş denetleyici, uzaktan medya oynatmanın tam kontrolüne sahip olan tam ekran görünümüdür. Bu görünüm, bir yayınlama uygulamasının Web Alıcısı ses kontrolü ve oturum yaşam döngüsü (bağlantı/yayını durdurma) hariç bir yayın oturumunun her yönetilebilir yönünü yönetmesine izin vermelidir. Medya oturumuyla ilgili tüm durum bilgilerini (ör. poster, başlık, alt başlık) da sağlar.

Bu görünümün işlevi GCKUIExpandedMediaControlsViewController sınıfı tarafından uygulanır.

Yapmanız gereken ilk şey, yayın bağlamında varsayılan genişletilmiş denetleyiciyi etkinleştirmektir. Varsayılan genişletilmiş denetleyiciyi etkinleştirmek için uygulama yetkisini değiştirin:

Hızlıca
func applicationDidFinishLaunching(_ application: UIApplication) {
  ..

  GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true

  ...
}
Objective-C
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  ...

  [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = YES;

  ..
}

Kullanıcı video yayınlamaya başladığında genişletilmiş denetleyiciyi yüklemek için görüntü denetleyicinize aşağıdaki kodu ekleyin:

Hızlıca
func playSelectedItemRemotely() {
  GCKCastContext.sharedInstance().presentDefaultExpandedMediaControls()

  ...

  // Load your media
  sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInformation)
}
Objective-C
- (void)playSelectedItemRemotely {
  [[GCKCastContext sharedInstance] presentDefaultExpandedMediaControls];

  ...

  // Load your media
  [self.sessionManager.currentSession.remoteMediaClient loadMedia:mediaInformation];
}

Genişletilmiş kumanda, kullanıcı mini kumandaya dokunduğunda da otomatik olarak başlatılır.

Gönderen uygulamanız video veya işitsel canlı yayın oynatırken SDK, genişletilmiş kumandadaki oynat/duraklat düğmesinin yerine otomatik olarak bir oynat/durdur düğmesi görüntüler.

Gönderen uygulamanızın Cast widget'larının görünümünü nasıl yapılandırabileceğini öğrenmek için iOS Uygulamanıza Özel Stiller Uygulama bölümüne bakın.

Ses düzeyi kontrolü

Cast çerçevesi, gönderen uygulamanın ses düzeyini otomatik olarak yönetir. Çerçeve, sağlanan kullanıcı arayüzü widget'ları için Web Alıcısı ses düzeyiyle otomatik olarak senkronize edilir. Uygulama tarafından sağlanan kaydırma çubuğunu senkronize etmek için GCKUIDeviceVolumeController aracını kullanın.

Fiziksel düğme ses seviyesi kontrolü

Gönderen cihazındaki fiziksel ses düğmeleri, GCKCastContext üzerinde ayarlı GCKCastOptions üzerindeki physicalVolumeButtonsWillControlDeviceVolume işaretini kullanarak Web Alıcısı'ndaki Yayın oturumunun ses düzeyini değiştirmek için kullanılabilir.

Hızlıca
let criteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID)
let options = GCKCastOptions(discoveryCriteria: criteria)
options.physicalVolumeButtonsWillControlDeviceVolume = true
GCKCastContext.setSharedInstanceWith(options)
Objective-C
GCKDiscoveryCriteria *criteria = [[GCKDiscoveryCriteria alloc]
                                          initWithApplicationID:kReceiverAppID];
GCKCastOptions *options = [[GCKCastOptions alloc]
                                          initWithDiscoveryCriteria :criteria];
options.physicalVolumeButtonsWillControlDeviceVolume = YES;
[GCKCastContext setSharedInstanceWithOptions:options];

Hataları işleme

Gönderen uygulamalarının tüm hata geri çağırmalarını işlemesi ve Cast yaşam döngüsünün her aşaması için en iyi yanıta karar vermesi çok önemlidir. Uygulama, kullanıcıya hata iletişim kutuları gösterebilir veya Yayın oturumunu sonlandırmaya karar verebilir.

Günlük Kaydı

GCKLogger, çerçeve tarafından günlük kaydı için kullanılan bir tekiltondur. Günlük mesajlarını işleme şeklinizi özelleştirmek için GCKLoggerDelegate aracını kullanın.

SDK, GCKLogger kullanarak hata ayıklama mesajları, hatalar ve uyarılar biçiminde bir günlük kaydı çıkışı üretir. Bu günlük mesajları hata ayıklamaya yardımcı olmanın yanı sıra sorun giderme ve tanımlama açısından kullanışlıdır. Varsayılan olarak, günlük çıkışı atlanır ancak gönderen uygulama bir GCKLoggerDelegate atayarak bu mesajları SDK'dan alabilir ve sistem konsoluna kaydedebilir.

Hızlıca
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GCKLoggerDelegate {
  let kReceiverAppID = kGCKDefaultMediaReceiverApplicationID
  let kDebugLoggingEnabled = true

  var window: UIWindow?

  func applicationDidFinishLaunching(_ application: UIApplication) {
    ...

    // Enable logger.
    GCKLogger.sharedInstance().delegate = self

    ...
  }

  // MARK: - GCKLoggerDelegate

  func logMessage(_ message: String,
                  at level: GCKLoggerLevel,
                  fromFunction function: String,
                  location: String) {
    if (kDebugLoggingEnabled) {
      print(function + " - " + message)
    }
  }
}
Objective-C

AppDelegate.h

@interface AppDelegate () <GCKLoggerDelegate>
@end

AppDelegate.m

@implementation AppDelegate

static NSString *const kReceiverAppID = @"AABBCCDD";
static const BOOL kDebugLoggingEnabled = YES;

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  ...

  // Enable logger.
  [GCKLogger sharedInstance].delegate = self;

  ...

  return YES;
}

...

#pragma mark - GCKLoggerDelegate

- (void)logMessage:(NSString *)message
           atLevel:(GCKLoggerLevel)level
      fromFunction:(NSString *)function
          location:(NSString *)location {
  if (kDebugLoggingEnabled) {
    NSLog(@"%@ - %@, %@", function, message, location);
  }
}

@end

Hata ayıklamayı ve ayrıntılı mesajları da etkinleştirmek için yetkiyi ayarladıktan sonra (daha önce gösterilen) koda şu satırı ekleyin:

Hızlıca
let filter = GCKLoggerFilter.init()
filter.minimumLevel = GCKLoggerLevel.verbose
GCKLogger.sharedInstance().filter = filter
Objective-C
GCKLoggerFilter *filter = [[GCKLoggerFilter alloc] init];
[filter setMinimumLevel:GCKLoggerLevelVerbose];
[GCKLogger sharedInstance].filter = filter;

GCKLogger tarafından oluşturulan günlük mesajlarını da filtreleyebilirsiniz. Sınıf başına minimum günlük kaydı düzeyini belirleyin. Örneğin:

Hızlıca
let filter = GCKLoggerFilter.init()
filter.setLoggingLevel(GCKLoggerLevel.verbose, forClasses: ["GCKUICastButton",
                                                            "GCKUIImageCache",
                                                            "NSMutableDictionary"])
GCKLogger.sharedInstance().filter = filter
Objective-C
GCKLoggerFilter *filter = [[GCKLoggerFilter alloc] init];
[filter setLoggingLevel:GCKLoggerLevelVerbose
             forClasses:@[@"GCKUICastButton",
                          @"GCKUIImageCache",
                          @"NSMutableDictionary"
                          ]];
[GCKLogger sharedInstance].filter = filter;

Sınıf adları ya değişmez adlar ya da glob kalıpları olabilir. Örneğin, GCKUI\* ve GCK\*Session.