Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Little iPhone Sample App for Uploading a Video to YouTube using gdata…

…-objectivec-client
  • Loading branch information...
commit 3b50a6723788162260076529e82fad3f357a2f14 0 parents
StuFF mc authored
5 .gitignore
@@ -0,0 +1,5 @@
+DerivedData
+YouTubeSample_iOS.xcodeproj/project.xcworkspace/xcuserdata
+YouTubeSample_iOS.xcodeproj/xcuserdata
+.DS_Store
+YouTubeSample_iOS/GoogleCredentials.h
1,254 YouTubeSample_iOS.xcodeproj/project.pbxproj
1,254 additions, 0 deletions not shown
7 YouTubeSample_iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:YouTubeSample_iOS.xcodeproj">
+ </FileRef>
+</Workspace>
15 YouTubeSample_iOS/AppDelegate.h
@@ -0,0 +1,15 @@
+//
+// AppDelegate.h
+// YouTubeSample_iOS
+//
+// Created by Manuel Carrasco Molina on 08.01.12.
+// Copyright (c) 2012 Pomcast. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+@end
66 YouTubeSample_iOS/AppDelegate.m
@@ -0,0 +1,66 @@
+//
+// AppDelegate.m
+// YouTubeSample_iOS
+//
+// Created by Manuel Carrasco Molina on 08.01.12.
+// Copyright (c) 2012 Pomcast. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@implementation AppDelegate
+
+@synthesize window = _window;
+
+- (void)dealloc
+{
+ [_window release];
+ [super dealloc];
+}
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application
+{
+ /*
+ Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+ */
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+ /*
+ Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+ */
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application
+{
+ /*
+ Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+ */
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application
+{
+ /*
+ Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+ */
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+ /*
+ Called when the application is about to terminate.
+ Save data if appropriate.
+ See also applicationDidEnterBackground:.
+ */
+}
+
+@end
11 YouTubeSample_iOS/Localizable.strings
@@ -0,0 +1,11 @@
+/*
+ Localizable.strings
+ YouTubeSample_iOS
+
+ Created by Manuel Carrasco Molina on 09.01.12.
+ Copyright (c) 2012 Pomcast. All rights reserved.
+*/
+
+"UPLOADED_VIDEO_MESSAGE" = "Uploaded video: %@";
+"UPLOADED_VIDEO_TITLE" = "Success!";
+"ERROR_UPLOAD_VIDEO_TITLE" = "Upload failed";
23 YouTubeSample_iOS/ViewController.h
@@ -0,0 +1,23 @@
+//
+// ViewController.h
+// YouTubeSample_iOS
+//
+// Created by Manuel Carrasco Molina on 08.01.12.
+// Copyright (c) 2012 Pomcast. All rights reserved.
+//
+
+// +----------------------------------------------------------------------------------------+
+// | See http://hoishing.wordpress.com/2011/08/23/gdata-objective-c-client-setup-in-xcode-4 |
+// +----------------------------------------------------------------------------------------+
+
+#import <UIKit/UIKit.h>
+#import "YouTubeUploader.h"
+
+@interface ViewController : UIViewController {
+
+ IBOutlet UIProgressView *uploadProgressView;
+}
+
+@property (nonatomic, retain) YouTubeUploader *youTubeUploader;
+
+@end
84 YouTubeSample_iOS/ViewController.m
@@ -0,0 +1,84 @@
+//
+// ViewController.m
+// YouTubeSample_iOS
+//
+// Created by Manuel Carrasco Molina on 08.01.12.
+// Copyright (c) 2012 Pomcast. All rights reserved.
+//
+
+#import "ViewController.h"
+
+@implementation ViewController
+
+@synthesize youTubeUploader = _youTubeUploader;
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Release any cached data, images, etc that aren't in use.
+}
+
+- (IBAction)upload:(id)sender {
+ self.youTubeUploader = [[YouTubeUploader alloc] init];
+ self.youTubeUploader.delegate = self;
+ self.youTubeUploader.uploadProgressView = uploadProgressView;
+ [self.youTubeUploader uploadVideoFile:@"/Users/mc/Movies/Temp/export.MOV"];
+}
+
+- (IBAction)logout:(id)sender {
+ [self.youTubeUploader logout];
+}
+
+#pragma mark - View lifecycle
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+}
+
+- (void)viewDidUnload
+{
+ [uploadProgressView release];
+ uploadProgressView = nil;
+ [_youTubeUploader release];
+ [super viewDidUnload];
+ // Release any retained subviews of the main view.
+ // e.g. self.myOutlet = nil;
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
+}
+
+- (void)viewDidAppear:(BOOL)animated
+{
+ [super viewDidAppear:animated];
+}
+
+- (void)viewWillDisappear:(BOOL)animated
+{
+ [super viewWillDisappear:animated];
+}
+
+- (void)viewDidDisappear:(BOOL)animated
+{
+ [super viewDidDisappear:animated];
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+ // Return YES for supported orientations
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
+ return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
+ } else {
+ return YES;
+ }
+}
+
+- (void)dealloc {
+ [uploadProgressView release];
+ [_youTubeUploader release];
+ [super dealloc];
+}
+@end
51 YouTubeSample_iOS/YouTubeSample_iOS-Info.plist
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFiles</key>
+ <array/>
+ <key>CFBundleIdentifier</key>
+ <string>biz.pomcast.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UIMainStoryboardFile</key>
+ <string>MainStoryboard_iPhone</string>
+ <key>UIMainStoryboardFile~ipad</key>
+ <string>MainStoryboard_iPad</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
14 YouTubeSample_iOS/YouTubeSample_iOS-Prefix.pch
@@ -0,0 +1,14 @@
+//
+// Prefix header for all source files of the 'YouTubeSample_iOS' target in the 'YouTubeSample_iOS' project
+//
+
+#import <Availability.h>
+
+#ifndef __IPHONE_5_0
+#warning "This project uses features only available in iOS SDK 5.0 and later."
+#endif
+
+#ifdef __OBJC__
+ #import <UIKit/UIKit.h>
+ #import <Foundation/Foundation.h>
+#endif
36 YouTubeSample_iOS/YouTubeUploader.h
@@ -0,0 +1,36 @@
+//
+// YouTubeUploader.h
+// YouTubeSample_iOS
+//
+// Created by Manuel Carrasco Molina on 08.01.12.
+// Copyright (c) 2012 Pomcast. All rights reserved.
+//
+
+// +----------------------------------------------------------------------------------------+
+// | See http://hoishing.wordpress.com/2011/08/23/gdata-objective-c-client-setup-in-xcode-4 |
+// +----------------------------------------------------------------------------------------+
+
+#import <Foundation/Foundation.h>
+#import "GData.h"
+#import "GoogleCredentials.h"
+// This "GoogleCredentials.h" file contains
+// #define DEV_KEY @"Find it at http://code.google.com/apis/youtube/dashboard/gwt/index.html"
+// #define CLIENT_ID @"Find it at https://code.google.com/apis/console under 'API Access'"
+// #define CLIENT_SECRET @"Find it there as well (GOOGLE APIs Console)"
+// The Google API console is also where you can set your Product Name and Logo (Image) that will be used in the Modal OAuth Window.
+
+// Localizable Strings Variables
+#define UPLOADED_VIDEO_TITLE @"UPLOADED_VIDEO_TITLE"
+#define UPLOADED_VIDEO_MESSAGE @"UPLOADED_VIDEO_MESSAGE"
+#define ERROR_UPLOAD_VIDEO_TITLE @"ERROR_UPLOAD_VIDEO_TITLE"
+
+@interface YouTubeUploader : NSObject {
+}
+
+@property (retain, nonatomic) UIProgressView *uploadProgressView;
+@property (assign) UIViewController *delegate;
+
+- (void)logout;
+- (void)uploadVideoFile:(NSString*)path;
+
+@end
194 YouTubeSample_iOS/YouTubeUploader.m
@@ -0,0 +1,194 @@
+//
+// YouTubeUploader.m
+// YouTubeSample_iOS
+//
+// Created by Manuel Carrasco Molina on 08.01.12.
+// Copyright (c) 2012 Pomcast. All rights reserved.
+//
+
+#import "YouTubeUploader.h"
+#import "GDataEntryYouTubeUpload.h"
+#import "GTMOAuth2ViewControllerTouch.h"
+
+@interface YouTubeUploader (Private)
+
+- (GDataServiceGoogleYouTube *)youTubeService;
+- (BOOL)isSignedIn;
+- (NSString *)signedInUsername;
+- (void)runSignin:(NSString*)path;
+
+@end
+
+@implementation YouTubeUploader
+
+@synthesize uploadProgressView = _uploadProgressView;
+@synthesize delegate = _delegate;
+
+static NSString *const kKeychainItemName = @"YouTubeSample_iOS: YouTube";
+
+#pragma mark - Public Methods
+
+- (id)init {
+ if ((self = [super init])) {
+ GTMOAuth2Authentication *auth;
+ auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
+ clientID:CLIENT_ID
+ clientSecret:CLIENT_SECRET];
+ [[self youTubeService] setAuthorizer:auth];
+ }
+ return self;
+}
+
+- (void)logout {
+ GDataServiceGoogleYouTube *service = [self youTubeService];
+ [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kKeychainItemName];
+ [service setAuthorizer:nil];
+ NSLog(@"Logged Out");
+}
+
+- (void)uploadVideoFile:(NSString*)path {
+ NSLog(@"About to upload %@", path);
+
+ if (![self isSignedIn]) {
+ // Sign in
+ [self runSignin:path];
+ }
+
+ GDataServiceGoogleYouTube *service = [self youTubeService];
+ [service setYouTubeDeveloperKey:DEV_KEY];
+
+ NSURL *url = [GDataServiceGoogleYouTube youTubeUploadURLForUserID:kGDataServiceDefaultUser];
+
+ // load the file data
+ NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
+ NSString *filename = [path lastPathComponent];
+
+ // gather all the metadata needed for the mediaGroup
+ GDataMediaTitle *title = [GDataMediaTitle textConstructWithString:[filename stringByDeletingPathExtension]];
+ GDataMediaCategory *category = [GDataMediaCategory mediaCategoryWithString:@"Entertainment"];
+ [category setScheme:kGDataSchemeYouTubeCategory];
+ BOOL isPrivate = YES;
+
+ GDataYouTubeMediaGroup *mediaGroup = [GDataYouTubeMediaGroup mediaGroup];
+ [mediaGroup setMediaTitle:title];
+ [mediaGroup addMediaCategory:category];
+ [mediaGroup setIsPrivate:isPrivate];
+
+ NSString *mimeType = [GDataUtilities MIMETypeForFileAtPath:path
+ defaultMIMEType:@"video/mp4"];
+
+ // create the upload entry with the mediaGroup and the file
+ GDataEntryYouTubeUpload *entry;
+ entry = [GDataEntryYouTubeUpload uploadEntryWithMediaGroup:mediaGroup
+ fileHandle:fileHandle
+ MIMEType:mimeType
+ slug:filename];
+
+ [service setServiceUploadProgressSelector:@selector(ticket:hasDeliveredByteCount:ofTotalByteCount:)];
+
+ GDataServiceTicket *ticket;
+ ticket = [service fetchEntryByInsertingEntry:entry
+ forFeedURL:url
+ delegate:self
+ didFinishSelector:@selector(uploadTicket:finishedWithEntry:error:)];
+}
+
+#pragma mark - Private Methods
+
+- (BOOL)isSignedIn {
+ NSString *name = [self signedInUsername];
+ NSLog(@"name: %@", name);
+ return (name != nil);
+}
+
+- (GDataServiceGoogleYouTube *)youTubeService {
+ // A "service" object handles networking tasks. Service objects
+ // contain user authentication information as well as networking
+ // state information (such as cookies and the "last modified" date for
+ // fetched data.)
+
+ static GDataServiceGoogleYouTube* service = nil;
+ if (!service) {
+ service = [[GDataServiceGoogleYouTube alloc] init];
+
+ [service setShouldCacheResponseData:YES];
+ [service setServiceShouldFollowNextLinks:YES];
+ [service setIsServiceRetryEnabled:YES];
+ }
+ [service setYouTubeDeveloperKey:DEV_KEY];
+ return service;
+}
+
+- (NSString *)signedInUsername {
+ // Get the email address of the signed-in user
+ GTMOAuth2Authentication *auth = [[self youTubeService] authorizer];
+ BOOL isSignedIn = auth.canAuthorize;
+ if (isSignedIn) {
+ return auth.userEmail;
+ } else {
+ return nil;
+ }
+}
+
+- (void)runSignin:(NSString*)path {
+ // Show the OAuth 2 sign-in controller
+ NSString *scope = [GDataServiceGoogleYouTube authorizationScope];
+
+ id completionHandler = ^(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error) {
+ // TODO: Check the error and don't dismiss if an error has occured.
+ NSLog(@"%@\n%@\n%@", viewController, auth, error);
+ [self.delegate dismissViewControllerAnimated:YES completion:^{
+ [self init];
+ if ([[[self youTubeService] authorizer] canAuthorize]) {
+ [self uploadVideoFile:path];
+ }
+ }];
+ };
+
+ GTMOAuth2ViewControllerTouch *viewController = [GTMOAuth2ViewControllerTouch controllerWithScope:scope
+ clientID:CLIENT_ID
+ clientSecret:CLIENT_SECRET
+ keychainItemName:kKeychainItemName
+ completionHandler:completionHandler];
+
+ [self.delegate presentViewController:viewController animated:YES completion:^{
+ NSLog(@"Google Sign In presented");
+ }];
+}
+
+// progress callback
+
+- (void)ticket:(GDataServiceTicket *)ticket hasDeliveredByteCount:(unsigned long long)numberOfBytesRead ofTotalByteCount:(unsigned long long)dataLength
+{
+ float progress = (float)numberOfBytesRead/dataLength;
+ NSLog(@"numberOfBytesRead/dataLength => %llu/%llu = %f",numberOfBytesRead, dataLength, progress);
+ [_uploadProgressView setProgress:progress animated:YES];
+}
+
+
+// upload callback
+- (void)uploadTicket:(GDataServiceTicket *)ticket
+ finishedWithEntry:(GDataEntryYouTubeVideo *)videoEntry
+ error:(NSError *)error {
+ NSLog(@"%@ %@", [videoEntry title], error);
+ NSString *title, *message;
+ if (error == nil) {
+ // tell the user that the add worked
+ title = NSLocalizedString(UPLOADED_VIDEO_TITLE, @"When the video upload succeeded ('title' in the UIAlertView).");
+ message = [NSString stringWithFormat:NSLocalizedString(UPLOADED_VIDEO_MESSAGE, @"When the video upload succeeded ('message' in the UIAlertView)."), [[videoEntry title] stringValue]];
+ } else {
+ title = NSLocalizedString(ERROR_UPLOAD_VIDEO_TITLE, @"When the video upload FAILED ('title' in the UIAlertView).");
+ message = [error localizedDescription];
+ }
+ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
+ [alertView show];
+ [alertView release];
+ [_uploadProgressView setProgress:0 animated:YES];
+}
+
+
+- (void)dealloc {
+ [_uploadProgressView release];
+ [super dealloc];
+}
+@end
2  YouTubeSample_iOS/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
27 YouTubeSample_iOS/en.lproj/MainStoryboard_iPad.storyboard
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="1.0" toolsVersion="1906" systemVersion="11A511" targetRuntime="iOS.CocoaTouch.iPad" nextObjectID="6" propertyAccessControl="none" initialViewController="2">
+ <dependencies>
+ <development defaultVersion="4200" identifier="xcode"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="902"/>
+ </dependencies>
+ <scenes>
+ <scene sceneID="4">
+ <objects>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="3" sceneMemberID="firstResponder"/>
+ <viewController id="2" customClass="ViewController" sceneMemberID="viewController">
+ <view key="view" contentMode="scaleToFill" id="5">
+ <rect key="frame" x="0.0" y="20" width="768" height="1004"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ </view>
+ </viewController>
+ </objects>
+ </scene>
+ </scenes>
+ <simulatedMetricsContainer key="defaultSimulatedMetrics">
+ <simulatedStatusBarMetrics key="statusBar" statusBarStyle="blackTranslucent"/>
+ <simulatedOrientationMetrics key="orientation"/>
+ <simulatedScreenMetrics key="destination"/>
+ </simulatedMetricsContainer>
+</document>
73 YouTubeSample_iOS/en.lproj/MainStoryboard_iPhone.storyboard
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="1.0" toolsVersion="1938" systemVersion="11C74" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="2">
+ <dependencies>
+ <development defaultVersion="4200" identifier="xcode"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="933"/>
+ </dependencies>
+ <scenes>
+ <scene sceneID="5">
+ <objects>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="4" sceneMemberID="firstResponder"/>
+ <viewController id="2" customClass="ViewController" sceneMemberID="viewController">
+ <view key="view" contentMode="scaleToFill" id="3">
+ <rect key="frame" x="0.0" y="20" width="320" height="460"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <subviews>
+ <progressView opaque="NO" contentMode="scaleToFill" id="D2c-uh-WKO">
+ <rect key="frame" x="20" y="225" width="280" height="9"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+ </progressView>
+ <button opaque="NO" tag="1" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="Psy-6M-t61">
+ <rect key="frame" x="122" y="150" width="76" height="37"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+ <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+ <state key="normal" title="Upload">
+ <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
+ </state>
+ <state key="highlighted">
+ <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ </state>
+ <connections>
+ <action selector="upload:" destination="2" eventType="touchUpInside" id="0SJ-KF-Vx7"/>
+ </connections>
+ </button>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="YFP-Qh-gl3">
+ <rect key="frame" x="122" y="282" width="76" height="37"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+ <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+ <state key="normal" title="Logout">
+ <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
+ </state>
+ <state key="highlighted">
+ <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ </state>
+ <connections>
+ <action selector="logout:" destination="2" eventType="touchUpInside" id="fW5-a6-77B"/>
+ </connections>
+ </button>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ </view>
+ <connections>
+ <outlet property="uploadProgressView" destination="D2c-uh-WKO" id="Kdh-GE-loa"/>
+ </connections>
+ </viewController>
+ </objects>
+ </scene>
+ </scenes>
+ <classes>
+ <class className="ViewController" superclassName="UIViewController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/ViewController.h"/>
+ <relationships>
+ <relationship kind="outlet" name="uploadProgressView" candidateClass="UIProgressView"/>
+ </relationships>
+ </class>
+ </classes>
+ <simulatedMetricsContainer key="defaultSimulatedMetrics">
+ <simulatedStatusBarMetrics key="statusBar"/>
+ <simulatedOrientationMetrics key="orientation"/>
+ <simulatedScreenMetrics key="destination"/>
+ </simulatedMetricsContainer>
+</document>
18 YouTubeSample_iOS/main.m
@@ -0,0 +1,18 @@
+//
+// main.m
+// YouTubeSample_iOS
+//
+// Created by Manuel Carrasco Molina on 08.01.12.
+// Copyright (c) 2012 Pomcast. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+#import "AppDelegate.h"
+
+int main(int argc, char *argv[])
+{
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
22 YouTubeSample_iOSTests/YouTubeSample_iOSTests-Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>biz.pomcast.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
13 YouTubeSample_iOSTests/YouTubeSample_iOSTests.h
@@ -0,0 +1,13 @@
+//
+// YouTubeSample_iOSTests.h
+// YouTubeSample_iOSTests
+//
+// Created by Manuel Carrasco Molina on 08.01.12.
+// Copyright (c) 2012 Pomcast. All rights reserved.
+//
+
+#import <SenTestingKit/SenTestingKit.h>
+
+@interface YouTubeSample_iOSTests : SenTestCase
+
+@end
32 YouTubeSample_iOSTests/YouTubeSample_iOSTests.m
@@ -0,0 +1,32 @@
+//
+// YouTubeSample_iOSTests.m
+// YouTubeSample_iOSTests
+//
+// Created by Manuel Carrasco Molina on 08.01.12.
+// Copyright (c) 2012 Pomcast. All rights reserved.
+//
+
+#import "YouTubeSample_iOSTests.h"
+
+@implementation YouTubeSample_iOSTests
+
+- (void)setUp
+{
+ [super setUp];
+
+ // Set-up code here.
+}
+
+- (void)tearDown
+{
+ // Tear-down code here.
+
+ [super tearDown];
+}
+
+- (void)testExample
+{
+ STFail(@"Unit tests are not implemented yet in YouTubeSample_iOSTests");
+}
+
+@end
2  YouTubeSample_iOSTests/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
Please sign in to comment.
Something went wrong with that request. Please try again.