new ui is almost fully functional
- add hosts - pair to host - get app list - launch app - resume app
@@ -47,6 +47,7 @@
|
|||||||
FB8946EB19F6AFE100339C8A /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB8946E019F6AFB800339C8A /* libcrypto.a */; };
|
FB8946EB19F6AFE100339C8A /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB8946E019F6AFB800339C8A /* libcrypto.a */; };
|
||||||
FB8946EC19F6AFE400339C8A /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB8946E119F6AFB800339C8A /* libssl.a */; };
|
FB8946EC19F6AFE400339C8A /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB8946E119F6AFB800339C8A /* libssl.a */; };
|
||||||
FB8946ED19F6AFE800339C8A /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB8946EA19F6AFB800339C8A /* libopus.a */; };
|
FB8946ED19F6AFE800339C8A /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB8946EA19F6AFB800339C8A /* libopus.a */; };
|
||||||
|
FBD3494319FC9C04002D2A60 /* AppManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3494219FC9C04002D2A60 /* AppManager.m */; };
|
||||||
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86DF19F7A837001C18A8 /* UIComputerView.m */; };
|
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86DF19F7A837001C18A8 /* UIComputerView.m */; };
|
||||||
FBDE86E619F82297001C18A8 /* UIAppView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86E519F82297001C18A8 /* UIAppView.m */; };
|
FBDE86E619F82297001C18A8 /* UIAppView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86E519F82297001C18A8 /* UIAppView.m */; };
|
||||||
FBDE86E919F82315001C18A8 /* App.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86E819F82315001C18A8 /* App.m */; };
|
FBDE86E919F82315001C18A8 /* App.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86E819F82315001C18A8 /* App.m */; };
|
||||||
@@ -214,12 +215,14 @@
|
|||||||
FB8946E719F6AFB800339C8A /* opus_multistream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opus_multistream.h; sourceTree = "<group>"; };
|
FB8946E719F6AFB800339C8A /* opus_multistream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opus_multistream.h; sourceTree = "<group>"; };
|
||||||
FB8946E819F6AFB800339C8A /* opus_types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opus_types.h; sourceTree = "<group>"; };
|
FB8946E819F6AFB800339C8A /* opus_types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opus_types.h; sourceTree = "<group>"; };
|
||||||
FB8946EA19F6AFB800339C8A /* libopus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libopus.a; sourceTree = "<group>"; };
|
FB8946EA19F6AFB800339C8A /* libopus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libopus.a; sourceTree = "<group>"; };
|
||||||
|
FBD3494119FC9C04002D2A60 /* AppManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppManager.h; sourceTree = "<group>"; };
|
||||||
|
FBD3494219FC9C04002D2A60 /* AppManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppManager.m; sourceTree = "<group>"; };
|
||||||
FBDE86DE19F7A837001C18A8 /* UIComputerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIComputerView.h; sourceTree = "<group>"; };
|
FBDE86DE19F7A837001C18A8 /* UIComputerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIComputerView.h; sourceTree = "<group>"; };
|
||||||
FBDE86DF19F7A837001C18A8 /* UIComputerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIComputerView.m; sourceTree = "<group>"; };
|
FBDE86DF19F7A837001C18A8 /* UIComputerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIComputerView.m; sourceTree = "<group>"; };
|
||||||
FBDE86E419F82297001C18A8 /* UIAppView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAppView.h; sourceTree = "<group>"; };
|
FBDE86E419F82297001C18A8 /* UIAppView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAppView.h; sourceTree = "<group>"; };
|
||||||
FBDE86E519F82297001C18A8 /* UIAppView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAppView.m; sourceTree = "<group>"; };
|
FBDE86E519F82297001C18A8 /* UIAppView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAppView.m; sourceTree = "<group>"; };
|
||||||
FBDE86E719F82315001C18A8 /* App.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = App.h; sourceTree = "<group>"; };
|
FBDE86E719F82315001C18A8 /* App.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = App.h; path = ../App.h; sourceTree = "<group>"; };
|
||||||
FBDE86E819F82315001C18A8 /* App.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = App.m; sourceTree = "<group>"; };
|
FBDE86E819F82315001C18A8 /* App.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = App.m; path = ../App.m; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -320,8 +323,6 @@
|
|||||||
FBDE86DF19F7A837001C18A8 /* UIComputerView.m */,
|
FBDE86DF19F7A837001C18A8 /* UIComputerView.m */,
|
||||||
FBDE86E419F82297001C18A8 /* UIAppView.h */,
|
FBDE86E419F82297001C18A8 /* UIAppView.h */,
|
||||||
FBDE86E519F82297001C18A8 /* UIAppView.m */,
|
FBDE86E519F82297001C18A8 /* UIAppView.m */,
|
||||||
FBDE86E719F82315001C18A8 /* App.h */,
|
|
||||||
FBDE86E819F82315001C18A8 /* App.m */,
|
|
||||||
);
|
);
|
||||||
path = Limelight;
|
path = Limelight;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -386,6 +387,8 @@
|
|||||||
FB89461219F646E200339C8A /* MDNSManager.m */,
|
FB89461219F646E200339C8A /* MDNSManager.m */,
|
||||||
FB89461319F646E200339C8A /* PairManager.h */,
|
FB89461319F646E200339C8A /* PairManager.h */,
|
||||||
FB89461419F646E200339C8A /* PairManager.m */,
|
FB89461419F646E200339C8A /* PairManager.m */,
|
||||||
|
FBD3494119FC9C04002D2A60 /* AppManager.h */,
|
||||||
|
FBD3494219FC9C04002D2A60 /* AppManager.m */,
|
||||||
);
|
);
|
||||||
path = Network;
|
path = Network;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -410,6 +413,8 @@
|
|||||||
children = (
|
children = (
|
||||||
FB89461F19F646E200339C8A /* Computer.h */,
|
FB89461F19F646E200339C8A /* Computer.h */,
|
||||||
FB89462019F646E200339C8A /* Computer.m */,
|
FB89462019F646E200339C8A /* Computer.m */,
|
||||||
|
FBDE86E719F82315001C18A8 /* App.h */,
|
||||||
|
FBDE86E819F82315001C18A8 /* App.m */,
|
||||||
FB89462119F646E200339C8A /* Utils.h */,
|
FB89462119F646E200339C8A /* Utils.h */,
|
||||||
FB89462219F646E200339C8A /* Utils.m */,
|
FB89462219F646E200339C8A /* Utils.m */,
|
||||||
);
|
);
|
||||||
@@ -725,6 +730,7 @@
|
|||||||
FB89462819F646E200339C8A /* CryptoManager.m in Sources */,
|
FB89462819F646E200339C8A /* CryptoManager.m in Sources */,
|
||||||
FB89462E19F646E200339C8A /* PairManager.m in Sources */,
|
FB89462E19F646E200339C8A /* PairManager.m in Sources */,
|
||||||
FB290D0019B2C406004C83CF /* main.m in Sources */,
|
FB290D0019B2C406004C83CF /* main.m in Sources */,
|
||||||
|
FBD3494319FC9C04002D2A60 /* AppManager.m in Sources */,
|
||||||
FB89462A19F646E200339C8A /* ControllerSupport.m in Sources */,
|
FB89462A19F646E200339C8A /* ControllerSupport.m in Sources */,
|
||||||
FB89463119F646E200339C8A /* StreamManager.m in Sources */,
|
FB89463119F646E200339C8A /* StreamManager.m in Sources */,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
@interface App : NSObject
|
@interface App : NSObject
|
||||||
|
|
||||||
@property NSString* displayName;
|
@property NSString* appId;
|
||||||
|
@property NSString* appName;
|
||||||
|
@property UIImage* appImage;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "App.h"
|
#import "App.h"
|
||||||
|
#import "HttpManager.h"
|
||||||
|
|
||||||
@implementation App
|
@implementation App
|
||||||
|
@synthesize appId, appName, appImage;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x",
|
||||||
|
"filename" : "limelight_computer_add_1x.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x",
|
||||||
|
"filename" : "limelight_computer_add_2x.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x",
|
||||||
|
"filename" : "limelight_computer_add_3x.png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x",
|
||||||
|
"filename" : "limelight_computer_add_icon_2x.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -3,7 +3,7 @@
|
|||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"filename" : "limelight_computer_2x-1.png"
|
"filename" : "limelight_computer_1x.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x",
|
"scale" : "3x",
|
||||||
"filename" : "limelight_computer_2x-2.png"
|
"filename" : "limelight_computer_3x.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
|
|||||||
|
After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x",
|
||||||
|
"filename" : "limelight_no_app_image_2x.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// AppManager.h
|
||||||
|
// Limelight
|
||||||
|
//
|
||||||
|
// Created by Diego Waxemberg on 10/25/14.
|
||||||
|
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "App.h"
|
||||||
|
#import "HttpManager.h"
|
||||||
|
|
||||||
|
@protocol AppAssetCallback <NSObject>
|
||||||
|
|
||||||
|
- (void) receivedAssetForApp:(App*)app;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface AppManager : NSObject
|
||||||
|
|
||||||
|
+ (void) retrieveAppAssets:(NSArray*)apps withManager:(HttpManager*)hMan andCallback:(id<AppAssetCallback>)callback;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
//
|
||||||
|
// AppManager.m
|
||||||
|
// Limelight
|
||||||
|
//
|
||||||
|
// Created by Diego Waxemberg on 10/25/14.
|
||||||
|
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "AppManager.h"
|
||||||
|
|
||||||
|
@implementation AppManager {
|
||||||
|
App* _app;
|
||||||
|
HttpManager* _hMan;
|
||||||
|
id<AppAssetCallback> _callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void) retrieveAppAssets:(NSArray*)apps withManager:(HttpManager*)hMan andCallback:(id<AppAssetCallback>)callback {
|
||||||
|
for (App* app in apps) {
|
||||||
|
AppManager* manager = [[AppManager alloc] initWithApp:app httpManager:hMan andCallback:callback];
|
||||||
|
[manager retrieveAsset];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWithApp:(App*)app httpManager:(HttpManager*)hMan andCallback:(id<AppAssetCallback>)callback {
|
||||||
|
self = [super init];
|
||||||
|
_app = app;
|
||||||
|
_hMan = hMan;
|
||||||
|
_callback = callback;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) retrieveAsset {
|
||||||
|
NSData* appAsset = [_hMan executeRequestSynchronously:[_hMan newAppAssetRequestWithAppId:_app.appId]];
|
||||||
|
UIImage* appImage = [UIImage imageWithData:appAsset];
|
||||||
|
_app.appImage = appImage;
|
||||||
|
NSLog(@"App Name: %@ id:%@ image: %@", _app.appName, _app.appId, _app.appImage);
|
||||||
|
[self performSelectorOnMainThread:@selector(sendCallBack) withObject:self waitUntilDone:NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) sendCallBack {
|
||||||
|
[_callback receivedAssetForApp:_app];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
@interface HttpManager : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
|
@interface HttpManager : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
|
||||||
|
|
||||||
|
+ (NSArray*) getAppListFromXML:(NSData*)xml;
|
||||||
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag;
|
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag;
|
||||||
+ (NSString*) getStatusStringFromXML:(NSData*)xml;
|
+ (NSString*) getStatusStringFromXML:(NSData*)xml;
|
||||||
|
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
- (NSURLRequest*) newServerInfoRequest;
|
- (NSURLRequest*) newServerInfoRequest;
|
||||||
- (NSURLRequest*) newLaunchRequest:(NSString*)appId width:(int)width height:(int)height refreshRate:(int)refreshRate rikey:(NSString*)rikey rikeyid:(int)rikeyid;
|
- (NSURLRequest*) newLaunchRequest:(NSString*)appId width:(int)width height:(int)height refreshRate:(int)refreshRate rikey:(NSString*)rikey rikeyid:(int)rikeyid;
|
||||||
- (NSURLRequest*) newResumeRequestWithRiKey:(NSString*)riKey riKeyId:(int)riKeyId;
|
- (NSURLRequest*) newResumeRequestWithRiKey:(NSString*)riKey riKeyId:(int)riKeyId;
|
||||||
|
- (NSURLRequest*) newAppAssetRequestWithAppId:(NSString*)appId;
|
||||||
- (NSData*) executeRequestSynchronously:(NSURLRequest*)request;
|
- (NSData*) executeRequestSynchronously:(NSURLRequest*)request;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#import "HttpManager.h"
|
#import "HttpManager.h"
|
||||||
#import "CryptoManager.h"
|
#import "CryptoManager.h"
|
||||||
|
#import "App.h"
|
||||||
|
|
||||||
#include <libxml2/libxml/xmlreader.h>
|
#include <libxml2/libxml/xmlreader.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -25,6 +26,60 @@
|
|||||||
|
|
||||||
static const NSString* PORT = @"47984";
|
static const NSString* PORT = @"47984";
|
||||||
|
|
||||||
|
+ (NSArray*) getAppListFromXML:(NSData*)xml {
|
||||||
|
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
||||||
|
|
||||||
|
if (docPtr == NULL) {
|
||||||
|
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlNodePtr node;
|
||||||
|
xmlNodePtr rootNode = node = xmlDocGetRootElement(docPtr);
|
||||||
|
|
||||||
|
// Check root status_code
|
||||||
|
if (![HttpManager verifyStatus: rootNode]) {
|
||||||
|
NSLog(@"ERROR: Request returned with failure status");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the root node
|
||||||
|
node = node->children;
|
||||||
|
|
||||||
|
NSMutableArray* appList = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
|
while (node != NULL) {
|
||||||
|
NSLog(@"node: %s", node->name);
|
||||||
|
if (!xmlStrcmp(node->name, (const xmlChar*)"App")) {
|
||||||
|
xmlNodePtr appInfoNode = node->xmlChildrenNode;
|
||||||
|
NSString* appName;
|
||||||
|
NSString* appId;
|
||||||
|
while (appInfoNode != NULL) {
|
||||||
|
NSLog(@"appInfoNode: %s", appInfoNode->name);
|
||||||
|
if (!xmlStrcmp(appInfoNode->name, (const xmlChar*)"AppTitle")) {
|
||||||
|
xmlChar* nodeVal = xmlNodeListGetString(docPtr, appInfoNode->xmlChildrenNode, 1);
|
||||||
|
appName = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||||
|
xmlFree(nodeVal);
|
||||||
|
} else if (!xmlStrcmp(appInfoNode->name, (const xmlChar*)"ID")) {
|
||||||
|
xmlChar* nodeVal = xmlNodeListGetString(docPtr, appInfoNode->xmlChildrenNode, 1);
|
||||||
|
appId = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||||
|
xmlFree(nodeVal);
|
||||||
|
}
|
||||||
|
appInfoNode = appInfoNode->next;
|
||||||
|
}
|
||||||
|
App* app = [[App alloc] init];
|
||||||
|
app.appName = appName;
|
||||||
|
app.appId = appId;
|
||||||
|
[appList addObject:app];
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
xmlFree(rootNode);
|
||||||
|
xmlFree(docPtr);
|
||||||
|
|
||||||
|
return appList;
|
||||||
|
}
|
||||||
|
|
||||||
+ (NSString*) getStatusStringFromXML:(NSData*)xml {
|
+ (NSString*) getStatusStringFromXML:(NSData*)xml {
|
||||||
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
||||||
|
|
||||||
@@ -198,6 +253,11 @@ static const NSString* PORT = @"47984";
|
|||||||
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSURLRequest*) newAppAssetRequestWithAppId:(NSString *)appId {
|
||||||
|
NSString* urlString = [NSString stringWithFormat:@"%@/appasset?uniqueid=%@&appid=%@&AssetType=2&AssetIdx=0", _baseURL, _uniqueId, appId];
|
||||||
|
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||||
|
}
|
||||||
|
|
||||||
- (NSString*) bytesToHex:(NSData*)data {
|
- (NSString*) bytesToHex:(NSData*)data {
|
||||||
const unsigned char* bytes = [data bytes];
|
const unsigned char* bytes = [data bytes];
|
||||||
NSMutableString *hex = [[NSMutableString alloc] init];
|
NSMutableString *hex = [[NSMutableString alloc] init];
|
||||||
@@ -217,7 +277,11 @@ static const NSString* PORT = @"47984";
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||||
_requestResp = [HttpManager fixXmlVersion:_respData];
|
if ([[NSString alloc] initWithData:_respData encoding:NSUTF8StringEncoding] != nil) {
|
||||||
|
_requestResp = [HttpManager fixXmlVersion:_respData];
|
||||||
|
} else {
|
||||||
|
_requestResp = _respData;
|
||||||
|
}
|
||||||
dispatch_semaphore_signal(_requestLock);
|
dispatch_semaphore_signal(_requestLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
- (void) showPIN:(NSString*)PIN;
|
- (void) showPIN:(NSString*)PIN;
|
||||||
- (void) pairSuccessful;
|
- (void) pairSuccessful;
|
||||||
- (void) pairFailed:(NSString*)message;
|
- (void) pairFailed:(NSString*)message;
|
||||||
|
- (void) alreadyPaired;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -32,14 +32,13 @@
|
|||||||
[_callback pairFailed:@"Unable to connect to PC"];
|
[_callback pairFailed:@"Unable to connect to PC"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (![[HttpManager getStringFromXML:serverInfo tag:@"currentgame"] isEqual:@"0"]) {
|
if (![[HttpManager getStringFromXML:serverInfo tag:@"currentgame"] isEqual:@"0"]) {
|
||||||
[_callback pairFailed:@"You must stop streaming before attempting to pair."];
|
[_callback pairFailed:@"You must stop streaming before attempting to pair."];
|
||||||
}
|
}
|
||||||
else if (![[HttpManager getStringFromXML:serverInfo tag:@"PairStatus"] isEqual:@"1"]) {
|
else if (![[HttpManager getStringFromXML:serverInfo tag:@"PairStatus"] isEqual:@"1"]) {
|
||||||
[self initiatePair];
|
[self initiatePair];
|
||||||
} else {
|
} else {
|
||||||
[_callback pairFailed:@"This device is already paired."];
|
[_callback alreadyPaired];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
@interface StreamConfiguration : NSObject
|
@interface StreamConfiguration : NSObject
|
||||||
|
|
||||||
@property NSString* host;
|
@property NSString* host;
|
||||||
|
@property NSString* appID;
|
||||||
@property int hostAddr;
|
@property int hostAddr;
|
||||||
@property int width;
|
@property int width;
|
||||||
@property int height;
|
@property int height;
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
#import "StreamConfiguration.h"
|
#import "StreamConfiguration.h"
|
||||||
|
|
||||||
@implementation StreamConfiguration
|
@implementation StreamConfiguration
|
||||||
@synthesize host, hostAddr, width, height, frameRate, bitRate, riKeyId, riKey;
|
@synthesize host, appID, hostAddr, width, height, frameRate, bitRate, riKeyId, riKey;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
NSData* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
NSData* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||||
NSString* currentGame = [HttpManager getStringFromXML:serverInfoResp tag:@"currentgame"];
|
NSString* currentGame = [HttpManager getStringFromXML:serverInfoResp tag:@"currentgame"];
|
||||||
NSString* pairStatus = [HttpManager getStringFromXML:serverInfoResp tag:@"PairStatus"];
|
NSString* pairStatus = [HttpManager getStringFromXML:serverInfoResp tag:@"PairStatus"];
|
||||||
|
NSString* currentClient = [HttpManager getStringFromXML:serverInfoResp tag:@"CurrentClient"];
|
||||||
if (currentGame == NULL || pairStatus == NULL) {
|
if (currentGame == NULL || pairStatus == NULL) {
|
||||||
[_callbacks launchFailed:@"Failed to connect to PC"];
|
[_callbacks launchFailed:@"Failed to connect to PC"];
|
||||||
return;
|
return;
|
||||||
@@ -55,6 +56,11 @@
|
|||||||
|
|
||||||
// resumeApp and launchApp handle calling launchFailed
|
// resumeApp and launchApp handle calling launchFailed
|
||||||
if (![currentGame isEqualToString:@"0"]) {
|
if (![currentGame isEqualToString:@"0"]) {
|
||||||
|
if (![currentClient isEqualToString:@"1"]) {
|
||||||
|
// The server is streaming to someone else
|
||||||
|
[_callbacks launchFailed:@"There is another stream in progress"];
|
||||||
|
return;
|
||||||
|
}
|
||||||
// App already running, resume it
|
// App already running, resume it
|
||||||
if (![self resumeApp:hMan]) {
|
if (![self resumeApp:hMan]) {
|
||||||
return;
|
return;
|
||||||
@@ -79,7 +85,7 @@
|
|||||||
|
|
||||||
- (BOOL) launchApp:(HttpManager*)hMan {
|
- (BOOL) launchApp:(HttpManager*)hMan {
|
||||||
NSData* launchResp = [hMan executeRequestSynchronously:
|
NSData* launchResp = [hMan executeRequestSynchronously:
|
||||||
[hMan newLaunchRequest:@"67339056"
|
[hMan newLaunchRequest:_config.appID
|
||||||
width:_config.width
|
width:_config.width
|
||||||
height:_config.height
|
height:_config.height
|
||||||
refreshRate:_config.frameRate
|
refreshRate:_config.frameRate
|
||||||
|
|||||||
@@ -9,8 +9,15 @@
|
|||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import "App.h"
|
#import "App.h"
|
||||||
|
|
||||||
@interface UIAppView : UIView
|
@protocol AppCallback <NSObject>
|
||||||
|
|
||||||
- (id) initWithApp:(App*)app;
|
- (void) appClicked:(App*) app;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface UIAppView : UIView
|
||||||
|
|
||||||
|
- (id) initWithApp:(App*)app andCallback:(id<AppCallback>)callback;
|
||||||
|
- (void) updateAppImage;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -12,32 +12,54 @@
|
|||||||
App* _app;
|
App* _app;
|
||||||
UIButton* _appButton;
|
UIButton* _appButton;
|
||||||
UILabel* _appLabel;
|
UILabel* _appLabel;
|
||||||
|
id<AppCallback> _callback;
|
||||||
}
|
}
|
||||||
static int LABEL_DY = 20;
|
static int LABEL_DY = 20;
|
||||||
|
|
||||||
- (id) initWithApp:(App*)app {
|
- (id) initWithApp:(App*)app andCallback:(id<AppCallback>)callback {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
_app = app;
|
_app = app;
|
||||||
|
_callback = callback;
|
||||||
|
|
||||||
_appButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
_appButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||||
[_appButton setContentEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
|
[_appButton setContentEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
|
||||||
[_appButton setBackgroundImage:[[UIImage imageNamed:@"Left4Dead2"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)] forState:UIControlStateNormal];
|
[_appButton setBackgroundImage:[UIImage imageNamed:@"NoAppImage"] forState:UIControlStateNormal];
|
||||||
[_appButton sizeToFit];
|
[_appButton sizeToFit];
|
||||||
|
[_appButton addTarget:self action:@selector(appClicked) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
_appButton.layer.shadowColor = [[UIColor blackColor] CGColor];
|
||||||
|
_appButton.layer.shadowOffset = CGSizeMake(5,8);
|
||||||
|
_appButton.layer.shadowOpacity = 0.7;
|
||||||
|
|
||||||
_appLabel = [[UILabel alloc] init];
|
_appLabel = [[UILabel alloc] init];
|
||||||
[_appLabel setText:_app.displayName];
|
[_appLabel setText:_app.appName];
|
||||||
[_appLabel sizeToFit];
|
[_appLabel sizeToFit];
|
||||||
_appLabel.center = CGPointMake(_appButton.bounds.origin.x + (_appButton.bounds.size.width / 2), _appButton.bounds.origin.y + _appButton.bounds.size.height + LABEL_DY);
|
_appLabel.center = CGPointMake(_appButton.bounds.origin.x + (_appButton.bounds.size.width / 2), _appButton.bounds.origin.y + _appButton.bounds.size.height + LABEL_DY);
|
||||||
|
|
||||||
|
[self updateBounds];
|
||||||
[self addSubview:_appButton];
|
[self addSubview:_appButton];
|
||||||
[self addSubview:_appLabel];
|
[self addSubview:_appLabel];
|
||||||
|
|
||||||
self.frame = CGRectMake(0, 0, _appButton.frame.size.width > _appLabel.frame.size.width ? _appButton.frame.size.width : _appLabel.frame.size.width, _appButton.frame.size.height + _appLabel.frame.size.height);
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) updateBounds {
|
||||||
|
float x = _appButton.frame.origin.x < _appLabel.frame.origin.x ? _appButton.frame.origin.x : _appLabel.frame.origin.x;
|
||||||
|
float y = _appButton.frame.origin.y < _appLabel.frame.origin.y ? _appButton.frame.origin.y : _appLabel.frame.origin.y;
|
||||||
|
self.bounds = CGRectMake(x , y, _appButton.frame.size.width > _appLabel.frame.size.width ? _appButton.frame.size.width : _appLabel.frame.size.width, _appButton.frame.size.height + _appLabel.frame.size.height + LABEL_DY / 2);
|
||||||
|
self.frame = CGRectMake(x , y, _appButton.frame.size.width > _appLabel.frame.size.width ? _appButton.frame.size.width : _appLabel.frame.size.width, _appButton.frame.size.height + _appLabel.frame.size.height + LABEL_DY / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) appClicked {
|
||||||
|
[_callback appClicked:_app];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) updateAppImage {
|
||||||
|
if (_app.appImage != nil) {
|
||||||
|
[_appButton setBackgroundImage:_app.appImage forState:UIControlStateNormal];
|
||||||
|
[self setNeedsDisplay];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Only override drawRect: if you perform custom drawing.
|
// Only override drawRect: if you perform custom drawing.
|
||||||
|
|||||||
@@ -9,8 +9,16 @@
|
|||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import "Computer.h"
|
#import "Computer.h"
|
||||||
|
|
||||||
@interface UIComputerView : UIView
|
@protocol HostCallback <NSObject>
|
||||||
|
|
||||||
- (id) initWithComputer:(Computer*)computer;
|
- (void) hostClicked:(Computer*)computer;
|
||||||
|
- (void) addHostClicked;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface UIComputerView : UIView
|
||||||
|
|
||||||
|
- (id) initWithComputer:(Computer*)computer andCallback:(id<HostCallback>)callback;
|
||||||
|
- (id) initForAddWithCallback:(id<HostCallback>)callback;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -12,31 +12,82 @@
|
|||||||
Computer* _computer;
|
Computer* _computer;
|
||||||
UIButton* _hostButton;
|
UIButton* _hostButton;
|
||||||
UILabel* _hostLabel;
|
UILabel* _hostLabel;
|
||||||
|
id<HostCallback> _callback;
|
||||||
|
CGSize _labelSize;
|
||||||
}
|
}
|
||||||
static int LABEL_DY = 20;
|
static int LABEL_DY = 20;
|
||||||
|
|
||||||
- (id) initWithComputer:(Computer*)computer {
|
- (id) init {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
_computer = computer;
|
|
||||||
|
|
||||||
_hostButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
_hostButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||||
[_hostButton setContentEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
|
[_hostButton setContentEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
|
||||||
[_hostButton setBackgroundImage:[[UIImage imageNamed:@"Computer"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)] forState:UIControlStateNormal];
|
[_hostButton setBackgroundImage:[UIImage imageNamed:@"Computer"] forState:UIControlStateNormal];
|
||||||
[_hostButton sizeToFit];
|
[_hostButton sizeToFit];
|
||||||
|
|
||||||
|
_hostButton.layer.shadowColor = [[UIColor blackColor] CGColor];
|
||||||
|
_hostButton.layer.shadowOffset = CGSizeMake(5,8);
|
||||||
|
_hostButton.layer.shadowOpacity = 0.7;
|
||||||
|
|
||||||
_hostLabel = [[UILabel alloc] init];
|
_hostLabel = [[UILabel alloc] init];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWithComputer:(Computer*)computer andCallback:(id<HostCallback>)callback {
|
||||||
|
self = [self init];
|
||||||
|
_computer = computer;
|
||||||
|
_callback = callback;
|
||||||
|
|
||||||
[_hostLabel setText:[_computer displayName]];
|
[_hostLabel setText:[_computer displayName]];
|
||||||
[_hostLabel sizeToFit];
|
[_hostLabel sizeToFit];
|
||||||
_hostLabel.center = CGPointMake(_hostButton.bounds.origin.x + (_hostButton.bounds.size.width / 2), _hostButton.bounds.origin.y + _hostButton.bounds.size.height + LABEL_DY);
|
[_hostButton addTarget:self action:@selector(hostClicked) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
_hostLabel.center = CGPointMake(_hostButton.frame.origin.x + (_hostButton.frame.size.width / 2), _hostButton.frame.origin.y + _hostButton.frame.size.height + LABEL_DY);
|
||||||
|
[self updateBounds];
|
||||||
[self addSubview:_hostButton];
|
[self addSubview:_hostButton];
|
||||||
[self addSubview:_hostLabel];
|
[self addSubview:_hostLabel];
|
||||||
|
|
||||||
self.frame = CGRectMake(0, 0, _hostButton.frame.size.width > _hostLabel.frame.size.width ? _hostButton.frame.size.width : _hostLabel.frame.size.width, _hostButton.frame.size.height + _hostLabel.frame.size.height);
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) updateBounds {
|
||||||
|
float x = _hostButton.frame.origin.x < _hostLabel.frame.origin.x ? _hostButton.frame.origin.x : _hostLabel.frame.origin.x;
|
||||||
|
float y = _hostButton.frame.origin.y < _hostLabel.frame.origin.y ? _hostButton.frame.origin.y : _hostLabel.frame.origin.y;
|
||||||
|
self.bounds = CGRectMake(x , y, _hostButton.frame.size.width > _hostLabel.frame.size.width ? _hostButton.frame.size.width : _hostLabel.frame.size.width, _hostButton.frame.size.height + _hostLabel.frame.size.height + LABEL_DY / 2);
|
||||||
|
self.frame = CGRectMake(x , y, _hostButton.frame.size.width > _hostLabel.frame.size.width ? _hostButton.frame.size.width : _hostLabel.frame.size.width, _hostButton.frame.size.height + _hostLabel.frame.size.height + LABEL_DY / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initForAddWithCallback:(id<HostCallback>)callback {
|
||||||
|
self = [self init];
|
||||||
|
_callback = callback;
|
||||||
|
|
||||||
|
[_hostButton setBackgroundImage:[UIImage imageNamed:@"Computer"] forState:UIControlStateNormal];
|
||||||
|
[_hostButton sizeToFit];
|
||||||
|
[_hostButton addTarget:self action:@selector(addClicked) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
|
||||||
|
[_hostLabel setText:@"Add Host"];
|
||||||
|
[_hostLabel sizeToFit];
|
||||||
|
_hostLabel.center = CGPointMake(_hostButton.frame.origin.x + (_hostButton.frame.size.width / 2), _hostButton.frame.origin.y + _hostButton.frame.size.height + LABEL_DY);
|
||||||
|
|
||||||
|
UIImageView* addIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"AddComputerIcon"]];
|
||||||
|
[addIcon sizeToFit];
|
||||||
|
addIcon.center = CGPointMake(_hostButton.frame.origin.x + _hostButton.frame.size.width, _hostButton.frame.origin.y);
|
||||||
|
|
||||||
|
[self updateBounds];
|
||||||
|
[self addSubview:_hostButton];
|
||||||
|
[self addSubview:_hostLabel];
|
||||||
|
[self addSubview:addIcon];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) hostClicked {
|
||||||
|
[_callback hostClicked:_computer];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) addClicked {
|
||||||
|
[_callback addHostClicked];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Only override drawRect: if you perform custom drawing.
|
// Only override drawRect: if you perform custom drawing.
|
||||||
// An empty implementation adversely affects performance during animation.
|
// An empty implementation adversely affects performance during animation.
|
||||||
|
|||||||
@@ -15,6 +15,5 @@
|
|||||||
|
|
||||||
- (id) initWithHost:(NSNetService*)host;
|
- (id) initWithHost:(NSNetService*)host;
|
||||||
- (id) initWithIp:(NSString*)host;
|
- (id) initWithIp:(NSString*)host;
|
||||||
- (id) initPlaceholder;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -28,13 +28,4 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initPlaceholder {
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
self.hostName = NULL;
|
|
||||||
self.displayName = @"No computers found";
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -10,8 +10,11 @@
|
|||||||
#import "MDNSManager.h"
|
#import "MDNSManager.h"
|
||||||
#import "PairManager.h"
|
#import "PairManager.h"
|
||||||
#import "StreamConfiguration.h"
|
#import "StreamConfiguration.h"
|
||||||
|
#import "UIComputerView.h"
|
||||||
|
#import "UIAppView.h"
|
||||||
|
#import "AppManager.h"
|
||||||
|
|
||||||
@interface MainFrameViewController : UIViewController <MDNSCallback, PairCallback, NSURLConnectionDelegate>
|
@interface MainFrameViewController : UIViewController <MDNSCallback, PairCallback, HostCallback, AppCallback, AppAssetCallback, NSURLConnectionDelegate>
|
||||||
|
|
||||||
+ (StreamConfiguration*) getStreamConfiguration;
|
+ (StreamConfiguration*) getStreamConfiguration;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// MainFrameViewController.m
|
// MainFrameViewController.m
|
||||||
// Limelight-iOS
|
// Limelight-iOS
|
||||||
//
|
//
|
||||||
@@ -22,45 +21,21 @@
|
|||||||
NSOperationQueue* _opQueue;
|
NSOperationQueue* _opQueue;
|
||||||
MDNSManager* _mDNSManager;
|
MDNSManager* _mDNSManager;
|
||||||
Computer* _selectedHost;
|
Computer* _selectedHost;
|
||||||
|
NSString* _uniqueId;
|
||||||
|
NSData* _cert;
|
||||||
|
|
||||||
UIAlertView* _pairAlert;
|
UIAlertView* _pairAlert;
|
||||||
|
UIScrollView* hostScrollView;
|
||||||
|
UIScrollView* appScrollView;
|
||||||
}
|
}
|
||||||
|
static NSString* deviceName = @"roth";
|
||||||
|
static NSMutableSet* hostList;
|
||||||
static StreamConfiguration* streamConfig;
|
static StreamConfiguration* streamConfig;
|
||||||
|
|
||||||
+ (StreamConfiguration*) getStreamConfiguration {
|
+ (StreamConfiguration*) getStreamConfiguration {
|
||||||
return streamConfig;
|
return streamConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: no more pair button
|
|
||||||
/*
|
|
||||||
- (void)PairButton:(UIButton *)sender
|
|
||||||
{
|
|
||||||
NSLog(@"Pair Button Pressed!");
|
|
||||||
if ([self.hostTextField.text length] > 0) {
|
|
||||||
_selectedHost = [[Computer alloc] initWithIp:self.hostTextField.text];
|
|
||||||
NSLog(@"Using custom host: %@", self.hostTextField.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (![self validatePcSelected]) {
|
|
||||||
NSLog(@"No valid PC selected");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CryptoManager generateKeyPairUsingSSl];
|
|
||||||
NSString* uniqueId = [CryptoManager getUniqueID];
|
|
||||||
NSData* cert = [CryptoManager readCertFromFile];
|
|
||||||
|
|
||||||
if ([Utils resolveHost:_selectedHost.hostName] == 0) {
|
|
||||||
[self displayDnsFailedDialog];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.hostName uniqueId:uniqueId deviceName:@"roth" cert:cert];
|
|
||||||
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:cert callback:self];
|
|
||||||
|
|
||||||
[_opQueue addOperation:pMan];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
- (void)showPIN:(NSString *)PIN {
|
- (void)showPIN:(NSString *)PIN {
|
||||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
_pairAlert = [[UIAlertView alloc] initWithTitle:@"Pairing" message:[NSString stringWithFormat:@"Enter the following PIN on the host machine: %@", PIN]delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
|
_pairAlert = [[UIAlertView alloc] initWithTitle:@"Pairing" message:[NSString stringWithFormat:@"Enter the following PIN on the host machine: %@", PIN]delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
|
||||||
@@ -84,6 +59,26 @@ static StreamConfiguration* streamConfig;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)alreadyPaired {
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
|
||||||
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.hostName uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||||
|
NSData* appListResp = [hMan executeRequestSynchronously:[hMan newAppListRequest]];
|
||||||
|
NSArray* appList = [HttpManager getAppListFromXML:appListResp];
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[self updateApps:appList];
|
||||||
|
});
|
||||||
|
[AppManager retrieveAppAssets:appList withManager:hMan andCallback:self];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) receivedAssetForApp:(App*)app {
|
||||||
|
NSArray* subviews = [appScrollView subviews];
|
||||||
|
for (UIAppView* appView in subviews) {
|
||||||
|
[appView updateAppImage];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)displayDnsFailedDialog {
|
- (void)displayDnsFailedDialog {
|
||||||
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Network Error"
|
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Network Error"
|
||||||
message:@"Failed to resolve host."
|
message:@"Failed to resolve host."
|
||||||
@@ -92,31 +87,55 @@ static StreamConfiguration* streamConfig;
|
|||||||
[self presentViewController:alert animated:YES completion:nil];
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: No more stream button
|
- (void) hostClicked:(Computer *)computer {
|
||||||
/*
|
NSLog(@"Clicked host: %@", computer.displayName);
|
||||||
- (void)StreamButton:(UIButton *)sender
|
_selectedHost = computer;
|
||||||
{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
NSLog(@"Stream Button Pressed!");
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:computer.hostName uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||||
|
NSData* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||||
|
if ([[HttpManager getStringFromXML:serverInfoResp tag:@"PairStatus"] isEqualToString:@"1"]) {
|
||||||
|
NSLog(@"Already Paired");
|
||||||
|
[self alreadyPaired];
|
||||||
|
} else {
|
||||||
|
NSLog(@"Trying to pair");
|
||||||
|
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:_cert callback:self];
|
||||||
|
[_opQueue addOperation:pMan];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if ([self.hostTextField.text length] > 0) {
|
- (void) addHostClicked {
|
||||||
_selectedHost = [[Computer alloc] initWithIp:self.hostTextField.text];
|
NSLog(@"Clicked add host");
|
||||||
NSLog(@"Using custom host: %@", self.hostTextField.text);
|
UIAlertController* alertController = [UIAlertController alertControllerWithTitle:@"Host Address" message:@"Please enter a hostname or IP address" preferredStyle:UIAlertControllerStyleAlert];
|
||||||
}
|
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
|
||||||
|
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||||
|
NSString* host = ((UITextField*)[[alertController textFields] objectAtIndex:0]).text;
|
||||||
|
Computer* newHost = [[Computer alloc] initWithIp:host];
|
||||||
|
[hostList addObject:newHost];
|
||||||
|
[self updateHosts:[hostList allObjects]];
|
||||||
|
|
||||||
if (![self validatePcSelected]) {
|
|
||||||
NSLog(@"No valid PC selected");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//TODO: get pair state
|
||||||
|
|
||||||
|
|
||||||
|
}]];
|
||||||
|
[alertController addTextFieldWithConfigurationHandler:nil];
|
||||||
|
[self presentViewController:alertController animated:YES completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) appClicked:(App *)app {
|
||||||
|
NSLog(@"Clicked app: %@", app.appName);
|
||||||
streamConfig = [[StreamConfiguration alloc] init];
|
streamConfig = [[StreamConfiguration alloc] init];
|
||||||
streamConfig.host = _selectedHost.hostName;
|
streamConfig.host = _selectedHost.hostName;
|
||||||
streamConfig.hostAddr = [Utils resolveHost:_selectedHost.hostName];
|
streamConfig.hostAddr = [Utils resolveHost:_selectedHost.hostName];
|
||||||
|
streamConfig.appID = app.appId;
|
||||||
if (streamConfig.hostAddr == 0) {
|
if (streamConfig.hostAddr == 0) {
|
||||||
[self displayDnsFailedDialog];
|
[self displayDnsFailedDialog];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long selectedConf = [self.StreamConfigs selectedRowInComponent:0];
|
// TODO: actually allow the user to choose the config
|
||||||
|
unsigned long selectedConf = 1;
|
||||||
NSLog(@"selectedConf: %ld", selectedConf);
|
NSLog(@"selectedConf: %ld", selectedConf);
|
||||||
switch (selectedConf) {
|
switch (selectedConf) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -148,19 +167,6 @@ static StreamConfiguration* streamConfig;
|
|||||||
NSLog(@"StreamConfig: %@, %d, %dx%dx%d at %d Mbps", streamConfig.host, streamConfig.hostAddr, streamConfig.width, streamConfig.height, streamConfig.frameRate, streamConfig.bitRate);
|
NSLog(@"StreamConfig: %@, %d, %dx%dx%d at %d Mbps", streamConfig.host, streamConfig.hostAddr, streamConfig.width, streamConfig.height, streamConfig.frameRate, streamConfig.bitRate);
|
||||||
[self performSegueWithIdentifier:@"createStreamFrame" sender:self];
|
[self performSegueWithIdentifier:@"createStreamFrame" sender:self];
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
- (void)setSelectedHost:(NSInteger)selectedIndex
|
|
||||||
{
|
|
||||||
_selectedHost = (Computer*)([self.hostPickerVals objectAtIndex:selectedIndex]);
|
|
||||||
if (_selectedHost.hostName == NULL) {
|
|
||||||
// This must be the placeholder computer
|
|
||||||
_selectedHost = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
- (void)viewDidLoad
|
- (void)viewDidLoad
|
||||||
{
|
{
|
||||||
@@ -169,68 +175,91 @@ static StreamConfiguration* streamConfig;
|
|||||||
NSArray* streamConfigVals = [[NSArray alloc] initWithObjects:@"1280x720 (30Hz)", @"1280x720 (60Hz)", @"1920x1080 (30Hz)", @"1920x1080 (60Hz)",nil];
|
NSArray* streamConfigVals = [[NSArray alloc] initWithObjects:@"1280x720 (30Hz)", @"1280x720 (60Hz)", @"1920x1080 (30Hz)", @"1920x1080 (60Hz)",nil];
|
||||||
|
|
||||||
_opQueue = [[NSOperationQueue alloc] init];
|
_opQueue = [[NSOperationQueue alloc] init];
|
||||||
|
[CryptoManager generateKeyPairUsingSSl];
|
||||||
|
_uniqueId = [CryptoManager getUniqueID];
|
||||||
|
_cert = [CryptoManager readCertFromFile];
|
||||||
|
|
||||||
// Initialize the host picker list
|
// Initialize the host picker list
|
||||||
//[self updateHosts:[[NSArray alloc] init]];
|
if (hostList == nil) {
|
||||||
|
hostList = [[NSMutableSet alloc] init];
|
||||||
Computer* test = [[Computer alloc] initWithIp:@"CEMENT-TRUCK"];
|
|
||||||
|
|
||||||
|
|
||||||
UIScrollView* hostScrollView = [[UIScrollView alloc] init];
|
|
||||||
hostScrollView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height / 2);
|
|
||||||
[hostScrollView setShowsHorizontalScrollIndicator:NO];
|
|
||||||
UIComputerView* compView;
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
compView = [[UIComputerView alloc] initWithComputer:test];
|
|
||||||
[hostScrollView addSubview:compView];
|
|
||||||
[compView sizeToFit];
|
|
||||||
compView.center = CGPointMake((compView.frame.size.width + 20) * i + compView.frame.size.width, hostScrollView.frame.size.height / 2);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[hostScrollView setContentSize:CGSizeMake(compView.frame.size.width * 5 + compView.frame.size.width, hostScrollView.frame.size.height)];
|
hostScrollView = [[UIScrollView alloc] init];
|
||||||
|
hostScrollView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height / 2);
|
||||||
|
[hostScrollView setShowsHorizontalScrollIndicator:NO];
|
||||||
|
|
||||||
|
appScrollView = [[UIScrollView alloc] init];
|
||||||
UIScrollView* appScrollView = [[UIScrollView alloc] init];
|
|
||||||
appScrollView.frame = CGRectMake(0, hostScrollView.frame.size.height, self.view.frame.size.width, self.view.frame.size.height / 2);
|
appScrollView.frame = CGRectMake(0, hostScrollView.frame.size.height, self.view.frame.size.width, self.view.frame.size.height / 2);
|
||||||
[appScrollView setShowsHorizontalScrollIndicator:NO];
|
[appScrollView setShowsHorizontalScrollIndicator:NO];
|
||||||
|
|
||||||
|
[self updateHosts:[hostList allObjects]];
|
||||||
App* testApp = [[App alloc] init];
|
|
||||||
testApp.displayName = @"Left 4 Dead 2";
|
|
||||||
UIAppView* appView;
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
appView = [[UIAppView alloc] initWithApp:testApp];
|
|
||||||
[appScrollView addSubview:appView];
|
|
||||||
[appView sizeToFit];
|
|
||||||
appView.center = CGPointMake((appView.frame.size.width + 20) * i + compView.frame.size.width, appScrollView.frame.size.height / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[appScrollView setContentSize:CGSizeMake(appView.frame.size.width * 5 + appView.frame.size.width, appScrollView.frame.size.height)];
|
|
||||||
|
|
||||||
[self.view addSubview:hostScrollView];
|
[self.view addSubview:hostScrollView];
|
||||||
[self.view addSubview:appScrollView];
|
[self.view addSubview:appScrollView];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidAppear:(BOOL)animated
|
- (void)viewDidAppear:(BOOL)animated
|
||||||
{
|
{
|
||||||
[super viewDidDisappear:animated];
|
[super viewDidDisappear:animated];
|
||||||
//_mDNSManager = [[MDNSManager alloc] initWithCallback:self];
|
_mDNSManager = [[MDNSManager alloc] initWithCallback:self];
|
||||||
// [_mDNSManager searchForHosts];
|
[_mDNSManager searchForHosts];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidDisappear:(BOOL)animated
|
- (void)viewDidDisappear:(BOOL)animated
|
||||||
{
|
{
|
||||||
[super viewDidDisappear:animated];
|
[super viewDidDisappear:animated];
|
||||||
// [_mDNSManager stopSearching];
|
[_mDNSManager stopSearching];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateHosts:(NSArray *)hosts {
|
- (void)updateHosts:(NSArray *)hosts {
|
||||||
NSMutableArray *hostPickerValues = [[NSMutableArray alloc] initWithArray:hosts];
|
[hostList addObjectsFromArray:hosts];
|
||||||
|
[[hostScrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||||
|
UIComputerView* addComp = [[UIComputerView alloc] initForAddWithCallback:self];
|
||||||
|
UIComputerView* compView;
|
||||||
|
float prevEdge = -1;
|
||||||
|
for (Computer* comp in hostList) {
|
||||||
|
compView = [[UIComputerView alloc] initWithComputer:comp andCallback:self];
|
||||||
|
compView.center = CGPointMake([self getCompViewX:compView addComp:addComp prevEdge:prevEdge], hostScrollView.frame.size.height / 2);
|
||||||
|
prevEdge = compView.frame.origin.x + compView.frame.size.width;
|
||||||
|
[hostScrollView addSubview:compView];
|
||||||
|
}
|
||||||
|
|
||||||
if ([hostPickerValues count] == 0) {
|
prevEdge = [self getCompViewX:addComp addComp:addComp prevEdge:prevEdge];
|
||||||
[hostPickerValues addObject:[[Computer alloc] initPlaceholder]];
|
addComp.center = CGPointMake(prevEdge, hostScrollView.frame.size.height / 2);
|
||||||
|
|
||||||
|
[hostScrollView addSubview:addComp];
|
||||||
|
[hostScrollView setContentSize:CGSizeMake(prevEdge + addComp.frame.size.width, hostScrollView.frame.size.height)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (float) getCompViewX:(UIComputerView*)comp addComp:(UIComputerView*)addComp prevEdge:(float)prevEdge {
|
||||||
|
if (prevEdge == -1) {
|
||||||
|
return hostScrollView.frame.origin.x + comp.frame.size.width / 2 + addComp.frame.size.width / 2;
|
||||||
|
} else {
|
||||||
|
return prevEdge + addComp.frame.size.width / 2 + comp.frame.size.width / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) updateApps:(NSArray*)apps {
|
||||||
|
[[appScrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||||
|
App* fakeApp = [[App alloc] init];
|
||||||
|
fakeApp.appName = @"No App Name";
|
||||||
|
UIAppView* noAppImage = [[UIAppView alloc] initWithApp:fakeApp andCallback:nil];
|
||||||
|
float prevEdge = -1;
|
||||||
|
UIAppView* appView;
|
||||||
|
for (App* app in apps) {
|
||||||
|
appView = [[UIAppView alloc] initWithApp:app andCallback:self];
|
||||||
|
prevEdge = [self getAppViewX:appView noApp:noAppImage prevEdge:prevEdge];
|
||||||
|
appView.center = CGPointMake(prevEdge, appScrollView.frame.size.height / 2);
|
||||||
|
prevEdge = appView.frame.origin.x + appView.frame.size.width;
|
||||||
|
[appScrollView addSubview:appView];
|
||||||
|
}
|
||||||
|
[appScrollView setContentSize:CGSizeMake(prevEdge + noAppImage.frame.size.width, appScrollView.frame.size.height)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (float) getAppViewX:(UIAppView*)app noApp:(UIAppView*)noAppImage prevEdge:(float)prevEdge {
|
||||||
|
if (prevEdge == -1) {
|
||||||
|
return appScrollView.frame.origin.x + app.frame.size.width / 2 + noAppImage.frame.size.width / 2;
|
||||||
|
} else {
|
||||||
|
return prevEdge + app.frame.size.width / 2 + noAppImage.frame.size.width / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
[self.stageLabel setText:@"Starting App"];
|
[self.stageLabel setText:@"Starting App"];
|
||||||
|
[self.stageLabel sizeToFit];
|
||||||
|
self.stageLabel.center = CGPointMake(self.view.frame.size.width / 2, self.stageLabel.center.y);
|
||||||
|
|
||||||
[UIApplication sharedApplication].idleTimerDisabled = YES;
|
[UIApplication sharedApplication].idleTimerDisabled = YES;
|
||||||
|
|
||||||
@@ -53,6 +55,8 @@
|
|||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[self.spinner stopAnimating];
|
[self.spinner stopAnimating];
|
||||||
[self.stageLabel setText:@"Waiting for first frame..."];
|
[self.stageLabel setText:@"Waiting for first frame..."];
|
||||||
|
[self.stageLabel sizeToFit];
|
||||||
|
self.stageLabel.center = CGPointMake(self.view.frame.size.width / 2, self.stageLabel.center.y);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,6 +78,8 @@
|
|||||||
NSString* lowerCase = [NSString stringWithFormat:@"%s in progress...", stageName];
|
NSString* lowerCase = [NSString stringWithFormat:@"%s in progress...", stageName];
|
||||||
NSString* titleCase = [[[lowerCase substringToIndex:1] uppercaseString] stringByAppendingString:[lowerCase substringFromIndex:1]];
|
NSString* titleCase = [[[lowerCase substringToIndex:1] uppercaseString] stringByAppendingString:[lowerCase substringFromIndex:1]];
|
||||||
[self.stageLabel setText:titleCase];
|
[self.stageLabel setText:titleCase];
|
||||||
|
[self.stageLabel sizeToFit];
|
||||||
|
self.stageLabel.center = CGPointMake(self.view.frame.size.width / 2, self.stageLabel.center.y);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" initialViewController="wb7-af-jn8">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="wb7-af-jn8">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@@ -8,21 +8,9 @@
|
|||||||
<scene sceneID="Me4-Nr-liz">
|
<scene sceneID="Me4-Nr-liz">
|
||||||
<objects>
|
<objects>
|
||||||
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
|
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||||
<layoutGuides>
|
|
||||||
<viewControllerLayoutGuide type="top" id="bBC-Wp-X5U"/>
|
|
||||||
<viewControllerLayoutGuide type="bottom" id="QeP-va-uIv"/>
|
|
||||||
</layoutGuides>
|
|
||||||
<view key="view" contentMode="scaleToFill" id="Icf-Kt-Ai7">
|
<view key="view" contentMode="scaleToFill" id="Icf-Kt-Ai7">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xyV-op-tQY">
|
|
||||||
<rect key="frame" x="564" y="470" width="42" height="21"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
</view>
|
</view>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||||
@@ -38,31 +26,23 @@
|
|||||||
<scene sceneID="RuD-qk-7nb">
|
<scene sceneID="RuD-qk-7nb">
|
||||||
<objects>
|
<objects>
|
||||||
<viewController storyboardIdentifier="MainFrame" id="OIm-0n-i9v" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
<viewController storyboardIdentifier="MainFrame" id="OIm-0n-i9v" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
||||||
<layoutGuides>
|
|
||||||
<viewControllerLayoutGuide type="top" id="NG3-N1-D4k"/>
|
|
||||||
<viewControllerLayoutGuide type="bottom" id="3MH-n6-BSR"/>
|
|
||||||
</layoutGuides>
|
|
||||||
<view key="view" contentMode="scaleToFill" id="VPm-Ae-rc4" userLabel="RenderView" customClass="StreamView">
|
<view key="view" contentMode="scaleToFill" id="VPm-Ae-rc4" userLabel="RenderView" customClass="StreamView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<activityIndicatorView opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" translatesAutoresizingMaskIntoConstraints="NO" id="iOs-1X-mSU">
|
<activityIndicatorView opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" id="iOs-1X-mSU">
|
||||||
<rect key="frame" x="502" y="374" width="20" height="20"/>
|
<rect key="frame" x="502" y="374" width="20" height="20"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dDs-kT-po6">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dDs-kT-po6">
|
||||||
<rect key="frame" x="491" y="402" width="42" height="21"/>
|
<rect key="frame" x="491" y="402" width="42" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="dDs-kT-po6" firstAttribute="top" secondItem="iOs-1X-mSU" secondAttribute="bottom" constant="8" id="VZj-wk-dHp"/>
|
|
||||||
<constraint firstAttribute="centerY" secondItem="iOs-1X-mSU" secondAttribute="centerY" id="YAN-0k-Rds"/>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="dDs-kT-po6" secondAttribute="centerX" id="bLr-5Z-OH3"/>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="iOs-1X-mSU" secondAttribute="centerX" id="ruD-8B-gj3"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
</view>
|
||||||
<nil key="simulatedStatusBarMetrics"/>
|
<nil key="simulatedStatusBarMetrics"/>
|
||||||
<nil key="simulatedTopBarMetrics"/>
|
<nil key="simulatedTopBarMetrics"/>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="dgh-JZ-Q7z">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="dgh-JZ-Q7z">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@@ -8,10 +8,6 @@
|
|||||||
<scene sceneID="emz-kO-L7q">
|
<scene sceneID="emz-kO-L7q">
|
||||||
<objects>
|
<objects>
|
||||||
<viewController id="dgh-JZ-Q7z" customClass="MainFrameViewController" sceneMemberID="viewController">
|
<viewController id="dgh-JZ-Q7z" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||||
<layoutGuides>
|
|
||||||
<viewControllerLayoutGuide type="top" id="udy-Vd-ca2"/>
|
|
||||||
<viewControllerLayoutGuide type="bottom" id="wiU-k0-6Q2"/>
|
|
||||||
</layoutGuides>
|
|
||||||
<view key="view" contentMode="scaleToFill" id="RId-Pb-IBX">
|
<view key="view" contentMode="scaleToFill" id="RId-Pb-IBX">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
@@ -32,31 +28,23 @@
|
|||||||
<scene sceneID="5Eb-q2-vjt">
|
<scene sceneID="5Eb-q2-vjt">
|
||||||
<objects>
|
<objects>
|
||||||
<viewController id="mI3-9F-XwU" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
<viewController id="mI3-9F-XwU" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
||||||
<layoutGuides>
|
|
||||||
<viewControllerLayoutGuide type="top" id="DRq-YB-9Rh"/>
|
|
||||||
<viewControllerLayoutGuide type="bottom" id="KH1-hM-RYW"/>
|
|
||||||
</layoutGuides>
|
|
||||||
<view key="view" contentMode="scaleToFill" id="eir-e9-IPE" customClass="StreamView">
|
<view key="view" contentMode="scaleToFill" id="eir-e9-IPE" customClass="StreamView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" translatesAutoresizingMaskIntoConstraints="NO" id="0vm-Iv-K4b">
|
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" id="0vm-Iv-K4b">
|
||||||
<rect key="frame" x="274" y="150" width="20" height="20"/>
|
<rect key="frame" x="274" y="150" width="20" height="20"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stage" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2HK-Z5-4Ch">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stage" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="2HK-Z5-4Ch">
|
||||||
<rect key="frame" x="262" y="178" width="45" height="21"/>
|
<rect key="frame" x="262" y="178" width="45" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="2HK-Z5-4Ch" secondAttribute="centerX" constant="-0.5" id="Blw-Hy-66z"/>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="0vm-Iv-K4b" secondAttribute="centerX" id="mCQ-CP-Yik"/>
|
|
||||||
<constraint firstAttribute="centerY" secondItem="0vm-Iv-K4b" secondAttribute="centerY" id="t8e-qp-g1j"/>
|
|
||||||
<constraint firstItem="2HK-Z5-4Ch" firstAttribute="top" secondItem="0vm-Iv-K4b" secondAttribute="bottom" constant="8" id="tta-Uo-bBO"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
</view>
|
||||||
<nil key="simulatedStatusBarMetrics"/>
|
<nil key="simulatedStatusBarMetrics"/>
|
||||||
<nil key="simulatedTopBarMetrics"/>
|
<nil key="simulatedTopBarMetrics"/>
|
||||||
|
|||||||