mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-10-22 16:17:47 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61b6e25a91 | ||
|
|
50cff820de | ||
|
|
4e586a28c8 | ||
|
|
0702b4ed57 | ||
|
|
4a2132a682 | ||
|
|
ba81d1d6a9 | ||
|
|
402ce4b3ec | ||
|
|
fc713453ad | ||
|
|
b222ccffbb | ||
|
|
56ce7329d2 | ||
|
|
99ab6db557 | ||
|
|
d7adf96f3a | ||
|
|
0ae58c61a9 | ||
|
|
2ec7d1d2f1 | ||
|
|
ad1b9059ee | ||
|
|
4439c7cce6 | ||
|
|
b8a4093c75 | ||
|
|
ec3748b26e | ||
|
|
1c1f22e047 | ||
|
|
9aa9b0fc5a | ||
|
|
f8e2ca8500 | ||
|
|
3076e29335 | ||
|
|
fe616d86c5 | ||
|
|
bfa4856bbe | ||
|
|
5ea92a7b48 |
No files matched your search
@@ -13,15 +13,14 @@
|
|||||||
|
|
||||||
+ (NSString*) getUniqueId {
|
+ (NSString*) getUniqueId {
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
Settings* prefs = [dataMan retrieveSettings];
|
|
||||||
|
NSString* uniqueId = [dataMan getUniqueId];
|
||||||
NSString* uniqueId = prefs.uniqueId;
|
|
||||||
if (uniqueId == nil) {
|
if (uniqueId == nil) {
|
||||||
uniqueId = [IdManager generateUniqueId];
|
uniqueId = [IdManager generateUniqueId];
|
||||||
prefs.uniqueId = uniqueId;
|
[dataMan updateUniqueId:uniqueId];
|
||||||
[dataMan saveData];
|
|
||||||
Log(LOG_I, @"No UUID found. Generated new UUID: %@", uniqueId);
|
Log(LOG_I, @"No UUID found. Generated new UUID: %@", uniqueId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return uniqueId;
|
return uniqueId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,16 +11,8 @@
|
|||||||
|
|
||||||
@class Host;
|
@class Host;
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface App : NSManagedObject
|
@interface App : NSManagedObject
|
||||||
|
|
||||||
@property BOOL isRunning;
|
|
||||||
|
|
||||||
- (NSComparisonResult)compareName:(App *)other;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
||||||
|
|
||||||
#import "App+CoreDataProperties.h"
|
#import "App+CoreDataProperties.h"
|
||||||
@@ -7,14 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "App.h"
|
#import "App.h"
|
||||||
#import "Host.h"
|
|
||||||
|
|
||||||
@implementation App
|
@implementation App
|
||||||
|
|
||||||
@synthesize isRunning;
|
|
||||||
|
|
||||||
- (NSComparisonResult)compareName:(App *)other {
|
|
||||||
return [self.name caseInsensitiveCompare:other.name];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -7,23 +7,25 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "Settings.h"
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "Host.h"
|
#import "TemporaryHost.h"
|
||||||
#import "App.h"
|
|
||||||
#import "TemporaryApp.h"
|
#import "TemporaryApp.h"
|
||||||
|
#import "TemporarySettings.h"
|
||||||
|
|
||||||
@interface DataManager : NSObject
|
@interface DataManager : NSObject
|
||||||
|
|
||||||
@property (strong, nonatomic) AppDelegate* appDelegate;
|
|
||||||
|
|
||||||
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls;
|
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls;
|
||||||
- (Settings*) retrieveSettings;
|
|
||||||
- (NSArray*) retrieveHosts;
|
- (NSArray*) getHosts;
|
||||||
- (void) saveData;
|
- (void) updateHost:(TemporaryHost*)host;
|
||||||
- (Host*) createHost;
|
- (void) updateAppsForExistingHost:(TemporaryHost *)host;
|
||||||
- (void) removeHost:(Host*)host;
|
- (void) updateIconForExistingApp:(TemporaryApp*)app;
|
||||||
- (App*) addAppFromTemporaryApp:(TemporaryApp*)tempApp;
|
- (void) removeHost:(TemporaryHost*)host;
|
||||||
- (void) removeAppFromHost:(App*)app;
|
- (void) removeApp:(TemporaryApp*)app;
|
||||||
|
|
||||||
|
- (TemporarySettings*) getSettings;
|
||||||
|
|
||||||
|
- (void) updateUniqueId:(NSString*)uniqueId;
|
||||||
|
- (NSString*) getUniqueId;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -8,45 +8,131 @@
|
|||||||
|
|
||||||
#import "DataManager.h"
|
#import "DataManager.h"
|
||||||
#import "TemporaryApp.h"
|
#import "TemporaryApp.h"
|
||||||
|
#import "TemporarySettings.h"
|
||||||
|
#import "Settings.h"
|
||||||
|
|
||||||
@implementation DataManager
|
@implementation DataManager {
|
||||||
|
NSManagedObjectContext *_managedObjectContext;
|
||||||
+ (NSObject *)databaseLock {
|
AppDelegate *_appDelegate;
|
||||||
static NSObject *lock = nil;
|
|
||||||
if (lock == nil) {
|
|
||||||
lock = [[NSObject alloc] init];
|
|
||||||
}
|
|
||||||
return lock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) init {
|
- (id) init {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
self.appDelegate = [[UIApplication sharedApplication] delegate];
|
|
||||||
|
_appDelegate = [[UIApplication sharedApplication] delegate];
|
||||||
|
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
|
||||||
|
[_managedObjectContext setPersistentStoreCoordinator:_appDelegate.persistentStoreCoordinator];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls {
|
- (void) updateUniqueId:(NSString*)uniqueId {
|
||||||
Settings* settingsToSave = [self retrieveSettings];
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
settingsToSave.framerate = [NSNumber numberWithInteger:framerate];
|
[self retrieveSettings].uniqueId = uniqueId;
|
||||||
// Bitrate is persisted in kbps
|
[self saveData];
|
||||||
settingsToSave.bitrate = [NSNumber numberWithInteger:bitrate];
|
}];
|
||||||
settingsToSave.height = [NSNumber numberWithInteger:height];
|
}
|
||||||
settingsToSave.width = [NSNumber numberWithInteger:width];
|
|
||||||
settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls];
|
|
||||||
|
|
||||||
NSError* error;
|
- (NSString*) getUniqueId {
|
||||||
if (![[self.appDelegate managedObjectContext] save:&error]) {
|
__block NSString *uid;
|
||||||
Log(LOG_E, @"Unable to save settings to database: %@", error);
|
|
||||||
}
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
[self.appDelegate saveContext];
|
uid = [self retrieveSettings].uniqueId;
|
||||||
|
}];
|
||||||
|
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls {
|
||||||
|
|
||||||
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
|
Settings* settingsToSave = [self retrieveSettings];
|
||||||
|
settingsToSave.framerate = [NSNumber numberWithInteger:framerate];
|
||||||
|
// Bitrate is persisted in kbps
|
||||||
|
settingsToSave.bitrate = [NSNumber numberWithInteger:bitrate];
|
||||||
|
settingsToSave.height = [NSNumber numberWithInteger:height];
|
||||||
|
settingsToSave.width = [NSNumber numberWithInteger:width];
|
||||||
|
settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls];
|
||||||
|
|
||||||
|
[self saveData];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) updateHost:(TemporaryHost *)host {
|
||||||
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
|
// Add a new persistent managed object if one doesn't exist
|
||||||
|
Host* parent = [self getHostForTemporaryHost:host withHostRecords:[self fetchRecords:@"Host"]];
|
||||||
|
if (parent == nil) {
|
||||||
|
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Host" inManagedObjectContext:_managedObjectContext];
|
||||||
|
parent = [[Host alloc] initWithEntity:entity insertIntoManagedObjectContext:_managedObjectContext];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push changes from the temp host to the persistent one
|
||||||
|
[host propagateChangesToParent:parent];
|
||||||
|
|
||||||
|
[self saveData];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) updateAppsForExistingHost:(TemporaryHost *)host {
|
||||||
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
|
Host* parent = [self getHostForTemporaryHost:host withHostRecords:[self fetchRecords:@"Host"]];
|
||||||
|
if (parent == nil) {
|
||||||
|
// The host must exist to be updated
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSMutableSet *applist = [[NSMutableSet alloc] init];
|
||||||
|
NSArray *appRecords = [self fetchRecords:@"App"];
|
||||||
|
for (TemporaryApp* app in host.appList) {
|
||||||
|
// Add a new persistent managed object if one doesn't exist
|
||||||
|
App* parentApp = [self getAppForTemporaryApp:app withAppRecords:appRecords];
|
||||||
|
if (parentApp == nil) {
|
||||||
|
NSEntityDescription* entity = [NSEntityDescription entityForName:@"App" inManagedObjectContext:_managedObjectContext];
|
||||||
|
parentApp = [[App alloc] initWithEntity:entity insertIntoManagedObjectContext:_managedObjectContext];
|
||||||
|
}
|
||||||
|
|
||||||
|
[app propagateChangesToParent:parentApp withHost:parent];
|
||||||
|
|
||||||
|
[applist addObject:parentApp];
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.appList = applist;
|
||||||
|
|
||||||
|
[self saveData];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) updateIconForExistingApp:(TemporaryApp*)app {
|
||||||
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
|
App* parentApp = [self getAppForTemporaryApp:app withAppRecords:[self fetchRecords:@"App"]];
|
||||||
|
if (parentApp == nil) {
|
||||||
|
// The app must exist to be updated
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parentApp.image = app.image;
|
||||||
|
|
||||||
|
[self saveData];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (TemporarySettings*) getSettings {
|
||||||
|
__block TemporarySettings *tempSettings;
|
||||||
|
|
||||||
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
|
tempSettings = [[TemporarySettings alloc] initFromSettings:[self retrieveSettings]];
|
||||||
|
}];
|
||||||
|
|
||||||
|
return tempSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (Settings*) retrieveSettings {
|
- (Settings*) retrieveSettings {
|
||||||
NSArray* fetchedRecords = [self fetchRecords:@"Settings"];
|
NSArray* fetchedRecords = [self fetchRecords:@"Settings"];
|
||||||
if (fetchedRecords.count == 0) {
|
if (fetchedRecords.count == 0) {
|
||||||
// create a new settings object with the default values
|
// create a new settings object with the default values
|
||||||
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Settings" inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Settings" inManagedObjectContext:_managedObjectContext];
|
||||||
Settings* settings = [[Settings alloc] initWithEntity:entity insertIntoManagedObjectContext:[self.appDelegate managedObjectContext]];
|
Settings* settings = [[Settings alloc] initWithEntity:entity insertIntoManagedObjectContext:_managedObjectContext];
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
} else {
|
} else {
|
||||||
@@ -55,74 +141,82 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (Host*) createHost {
|
- (void) removeApp:(TemporaryApp*)app {
|
||||||
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Host" inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
return [[Host alloc] initWithEntity:entity insertIntoManagedObjectContext:[self.appDelegate managedObjectContext]];
|
App* managedApp = [self getAppForTemporaryApp:app withAppRecords:[self fetchRecords:@"App"]];
|
||||||
|
if (managedApp != nil) {
|
||||||
|
[_managedObjectContext deleteObject:managedApp];
|
||||||
|
[self saveData];
|
||||||
|
}
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeHost:(Host*)host {
|
- (void) removeHost:(TemporaryHost*)host {
|
||||||
[[self.appDelegate managedObjectContext] deleteObject:host];
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
[self saveData];
|
Host* managedHost = [self getHostForTemporaryHost:host withHostRecords:[self fetchRecords:@"Host"]];
|
||||||
|
if (managedHost != nil) {
|
||||||
|
[_managedObjectContext deleteObject:managedHost];
|
||||||
|
[self saveData];
|
||||||
|
}
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) saveData {
|
- (void) saveData {
|
||||||
@synchronized([DataManager databaseLock]) {
|
NSError* error;
|
||||||
NSError* error;
|
if (![_managedObjectContext save:&error]) {
|
||||||
if (![[self.appDelegate managedObjectContext] save:&error]) {
|
Log(LOG_E, @"Unable to save hosts to database: %@", error);
|
||||||
Log(LOG_E, @"Unable to save hosts to database: %@", error);
|
}
|
||||||
|
|
||||||
|
[_appDelegate saveContext];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray*) getHosts {
|
||||||
|
__block NSMutableArray *tempHosts = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
|
NSArray *hosts = [self fetchRecords:@"Host"];
|
||||||
|
|
||||||
|
for (Host* host in hosts) {
|
||||||
|
[tempHosts addObject:[[TemporaryHost alloc] initFromHost:host]];
|
||||||
}
|
}
|
||||||
[self.appDelegate saveContext];
|
}];
|
||||||
}
|
|
||||||
|
return tempHosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray*) retrieveHosts {
|
// Only call from within performBlockAndWait!!!
|
||||||
return [self fetchRecords:@"Host"];
|
- (Host*) getHostForTemporaryHost:(TemporaryHost*)tempHost withHostRecords:(NSArray*)hosts {
|
||||||
}
|
for (Host* host in hosts) {
|
||||||
|
if ([tempHost.uuid isEqualToString:host.uuid]) {
|
||||||
- (App*) addAppFromTemporaryApp:(TemporaryApp*)tempApp {
|
return host;
|
||||||
|
}
|
||||||
App* managedApp;
|
|
||||||
|
|
||||||
@synchronized([DataManager databaseLock]) {
|
|
||||||
NSEntityDescription* entity = [NSEntityDescription entityForName:@"App" inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
|
||||||
managedApp = [[App alloc] initWithEntity:entity insertIntoManagedObjectContext:[self.appDelegate managedObjectContext]];
|
|
||||||
|
|
||||||
assert(tempApp.host != nil);
|
|
||||||
|
|
||||||
managedApp.id = tempApp.id;
|
|
||||||
managedApp.image = tempApp.image;
|
|
||||||
managedApp.name = tempApp.name;
|
|
||||||
managedApp.isRunning = tempApp.isRunning;
|
|
||||||
managedApp.host = tempApp.host;
|
|
||||||
|
|
||||||
[managedApp.host addAppListObject:managedApp];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return managedApp;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeAppFromHost:(App*)app {
|
// Only call from within performBlockAndWait!!!
|
||||||
@synchronized([DataManager databaseLock]) {
|
- (App*) getAppForTemporaryApp:(TemporaryApp*)tempApp withAppRecords:(NSArray*)apps {
|
||||||
assert(app.host != nil);
|
for (App* app in apps) {
|
||||||
|
if ([app.id isEqualToString:tempApp.id] &&
|
||||||
[app.host removeAppListObject:app];
|
[app.host.uuid isEqualToString:app.host.uuid]) {
|
||||||
[[self.appDelegate managedObjectContext] deleteObject:app];
|
return app;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray*) fetchRecords:(NSString*)entityName {
|
- (NSArray*) fetchRecords:(NSString*)entityName {
|
||||||
NSArray* fetchedRecords;
|
NSArray* fetchedRecords;
|
||||||
|
|
||||||
@synchronized([DataManager databaseLock]) {
|
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
|
||||||
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
|
NSEntityDescription* entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:_managedObjectContext];
|
||||||
NSEntityDescription* entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
[fetchRequest setEntity:entity];
|
||||||
[fetchRequest setEntity:entity];
|
|
||||||
[fetchRequest setAffectedStores:[NSArray arrayWithObjects:[[self.appDelegate persistentStoreCoordinator] persistentStoreForURL:[self.appDelegate getStoreURL]], nil]];
|
NSError* error;
|
||||||
|
fetchedRecords = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
|
||||||
NSError* error;
|
//TODO: handle errors
|
||||||
fetchedRecords = [[self.appDelegate managedObjectContext] executeFetchRequest:fetchRequest error:&error];
|
|
||||||
//TODO: handle errors
|
|
||||||
}
|
|
||||||
|
|
||||||
return fetchedRecords;
|
return fetchedRecords;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,18 +10,8 @@
|
|||||||
#import <CoreData/CoreData.h>
|
#import <CoreData/CoreData.h>
|
||||||
#import "Utils.h"
|
#import "Utils.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface Host : NSManagedObject
|
@interface Host : NSManagedObject
|
||||||
|
|
||||||
@property (nonatomic) BOOL online;
|
|
||||||
@property (nonatomic) PairState pairState;
|
|
||||||
@property (nonatomic) NSString * activeAddress;
|
|
||||||
|
|
||||||
- (NSComparisonResult)compareName:(Host *)other;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
||||||
|
|
||||||
#import "Host+CoreDataProperties.h"
|
#import "Host+CoreDataProperties.h"
|
||||||
@@ -10,12 +10,4 @@
|
|||||||
|
|
||||||
@implementation Host
|
@implementation Host
|
||||||
|
|
||||||
@dynamic pairState;
|
|
||||||
@synthesize online;
|
|
||||||
@synthesize activeAddress;
|
|
||||||
|
|
||||||
- (NSComparisonResult)compareName:(Host *)other {
|
|
||||||
return [self.name caseInsensitiveCompare:other.name];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "Host.h"
|
#import "TemporaryHost.h"
|
||||||
|
#import "App.h"
|
||||||
|
|
||||||
@interface TemporaryApp : NSObject
|
@interface TemporaryApp : NSObject
|
||||||
|
|
||||||
@@ -15,6 +16,16 @@
|
|||||||
@property (nullable, nonatomic, retain) NSData *image;
|
@property (nullable, nonatomic, retain) NSData *image;
|
||||||
@property (nullable, nonatomic, retain) NSString *name;
|
@property (nullable, nonatomic, retain) NSString *name;
|
||||||
@property (nonatomic) BOOL isRunning;
|
@property (nonatomic) BOOL isRunning;
|
||||||
@property (nullable, nonatomic, retain) Host *host;
|
@property (nullable, nonatomic, retain) TemporaryHost *host;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
- (id) initFromApp:(App*)app withTempHost:(TemporaryHost*)tempHost;
|
||||||
|
|
||||||
|
- (NSComparisonResult)compareName:(TemporaryApp *)other;
|
||||||
|
|
||||||
|
- (void) propagateChangesToParent:(App*)parent withHost:(Host*)host;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -7,7 +7,46 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "TemporaryApp.h"
|
#import "TemporaryApp.h"
|
||||||
|
#import "App.h"
|
||||||
|
|
||||||
@implementation TemporaryApp
|
@implementation TemporaryApp
|
||||||
|
|
||||||
|
- (id) initFromApp:(App*)app withTempHost:(TemporaryHost*)tempHost {
|
||||||
|
self = [self init];
|
||||||
|
|
||||||
|
self.id = app.id;
|
||||||
|
self.image = app.image;
|
||||||
|
self.name = app.name;
|
||||||
|
self.host = tempHost;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) propagateChangesToParent:(App*)parent withHost:(Host*)host {
|
||||||
|
parent.id = self.id;
|
||||||
|
parent.name = self.name;
|
||||||
|
parent.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSComparisonResult)compareName:(TemporaryApp *)other {
|
||||||
|
return [self.name caseInsensitiveCompare:other.name];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSUInteger)hash {
|
||||||
|
return [self.host.uuid hash] * 31 + [self.id intValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isEqual:(id)object {
|
||||||
|
if (self == object) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![object isKindOfClass:[App class]]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [self.host.uuid isEqualToString:((App*)object).host.uuid] &&
|
||||||
|
[self.id isEqualToString:((App*)object).id];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// TemporaryHost.h
|
||||||
|
// Moonlight
|
||||||
|
//
|
||||||
|
// Created by Cameron Gutman on 12/1/15.
|
||||||
|
// Copyright © 2015 Moonlight Stream. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "Utils.h"
|
||||||
|
#import "Host.h"
|
||||||
|
|
||||||
|
@interface TemporaryHost : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic) BOOL online;
|
||||||
|
@property (nonatomic) PairState pairState;
|
||||||
|
@property (nonatomic, nullable) NSString * activeAddress;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@property (nonatomic, retain) NSString *address;
|
||||||
|
@property (nonatomic, retain) NSString *externalAddress;
|
||||||
|
@property (nonatomic, retain) NSString *localAddress;
|
||||||
|
@property (nonatomic, retain) NSString *mac;
|
||||||
|
@property (nonatomic, retain) NSString *name;
|
||||||
|
@property (nonatomic, retain) NSString *uuid;
|
||||||
|
@property (nonatomic, retain) NSMutableSet *appList;
|
||||||
|
|
||||||
|
- (id) initFromHost:(Host*)host;
|
||||||
|
|
||||||
|
- (NSComparisonResult)compareName:(TemporaryHost *)other;
|
||||||
|
|
||||||
|
- (void) propagateChangesToParent:(Host*)host;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// TemporaryHost.m
|
||||||
|
// Moonlight
|
||||||
|
//
|
||||||
|
// Created by Cameron Gutman on 12/1/15.
|
||||||
|
// Copyright © 2015 Moonlight Stream. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "DataManager.h"
|
||||||
|
#import "TemporaryHost.h"
|
||||||
|
#import "Host.h"
|
||||||
|
#import "TemporaryApp.h"
|
||||||
|
#import "App.h"
|
||||||
|
|
||||||
|
@implementation TemporaryHost
|
||||||
|
|
||||||
|
- (id) init {
|
||||||
|
self = [super init];
|
||||||
|
self.appList = [[NSMutableSet alloc] init];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initFromHost:(Host*)host {
|
||||||
|
self = [self init];
|
||||||
|
|
||||||
|
self.address = host.address;
|
||||||
|
self.externalAddress = host.externalAddress;
|
||||||
|
self.localAddress = host.localAddress;
|
||||||
|
self.mac = host.mac;
|
||||||
|
self.name = host.name;
|
||||||
|
self.uuid = host.uuid;
|
||||||
|
self.pairState = [host.pairState intValue];
|
||||||
|
|
||||||
|
NSMutableSet *appList = [[NSMutableSet alloc] init];
|
||||||
|
|
||||||
|
for (App* app in host.appList) {
|
||||||
|
TemporaryApp *tempApp = [[TemporaryApp alloc] initFromApp:app withTempHost:self];
|
||||||
|
[appList addObject:tempApp];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.appList = appList;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) propagateChangesToParent:(Host*)parentHost {
|
||||||
|
parentHost.address = self.address;
|
||||||
|
parentHost.externalAddress = self.externalAddress;
|
||||||
|
parentHost.localAddress = self.localAddress;
|
||||||
|
parentHost.mac = self.mac;
|
||||||
|
parentHost.name = self.name;
|
||||||
|
parentHost.uuid = self.uuid;
|
||||||
|
parentHost.pairState = [NSNumber numberWithInt:self.pairState];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSComparisonResult)compareName:(TemporaryHost *)other {
|
||||||
|
return [self.name caseInsensitiveCompare:other.name];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSUInteger)hash {
|
||||||
|
return [self.uuid hash];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isEqual:(id)object {
|
||||||
|
if (self == object) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![object isKindOfClass:[Host class]]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [self.uuid isEqualToString:((Host*)object).uuid];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// TemporarySettings.h
|
||||||
|
// Moonlight
|
||||||
|
//
|
||||||
|
// Created by Cameron Gutman on 12/1/15.
|
||||||
|
// Copyright © 2015 Moonlight Stream. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "Settings.h"
|
||||||
|
|
||||||
|
@interface TemporarySettings : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, retain) Settings * parent;
|
||||||
|
|
||||||
|
@property (nonatomic, retain) NSNumber * bitrate;
|
||||||
|
@property (nonatomic, retain) NSNumber * framerate;
|
||||||
|
@property (nonatomic, retain) NSNumber * height;
|
||||||
|
@property (nonatomic, retain) NSNumber * width;
|
||||||
|
@property (nonatomic, retain) NSNumber * onscreenControls;
|
||||||
|
@property (nonatomic, retain) NSString * uniqueId;
|
||||||
|
|
||||||
|
- (id) initFromSettings:(Settings*)settings;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// TemporarySettings.m
|
||||||
|
// Moonlight
|
||||||
|
//
|
||||||
|
// Created by Cameron Gutman on 12/1/15.
|
||||||
|
// Copyright © 2015 Moonlight Stream. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "TemporarySettings.h"
|
||||||
|
|
||||||
|
@implementation TemporarySettings
|
||||||
|
|
||||||
|
- (id) initFromSettings:(Settings*)settings {
|
||||||
|
self = [self init];
|
||||||
|
|
||||||
|
self.parent = settings;
|
||||||
|
|
||||||
|
self.bitrate = settings.bitrate;
|
||||||
|
self.framerate = settings.framerate;
|
||||||
|
self.height = settings.height;
|
||||||
|
self.width = settings.width;
|
||||||
|
self.onscreenControls = settings.onscreenControls;
|
||||||
|
self.uniqueId = settings.uniqueId;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -71,6 +71,12 @@
|
|||||||
"idiom" : "ipad",
|
"idiom" : "ipad",
|
||||||
"filename" : "app_icon_152x152_@2x.png",
|
"filename" : "app_icon_152x152_@2x.png",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "83.5x83.5",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "app_icon_167x167_@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
@@ -32,7 +32,7 @@
|
|||||||
- (void) setupOnScreenControls:(ControllerSupport*)controllerSupport swipeDelegate:(id<EdgeDetectionDelegate>)swipeDelegate {
|
- (void) setupOnScreenControls:(ControllerSupport*)controllerSupport swipeDelegate:(id<EdgeDetectionDelegate>)swipeDelegate {
|
||||||
onScreenControls = [[OnScreenControls alloc] initWithView:self controllerSup:controllerSupport swipeDelegate:swipeDelegate];
|
onScreenControls = [[OnScreenControls alloc] initWithView:self controllerSup:controllerSupport swipeDelegate:swipeDelegate];
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
OnScreenControlsLevel level = (OnScreenControlsLevel)[[dataMan retrieveSettings].onscreenControls integerValue];
|
OnScreenControlsLevel level = (OnScreenControlsLevel)[[dataMan getSettings].onscreenControls integerValue];
|
||||||
|
|
||||||
if (level == OnScreenControlsLevelAuto) {
|
if (level == OnScreenControlsLevelAuto) {
|
||||||
[controllerSupport initAutoOnScreenControlMode:onScreenControls];
|
[controllerSupport initAutoOnScreenControlMode:onScreenControls];
|
||||||
|
|||||||
@@ -17,11 +17,11 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.0.1</string>
|
<string>1.0.3</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>4</string>
|
<string>1</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.games</string>
|
<string>public.app-category.games</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
|||||||
@@ -7,20 +7,20 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "App.h"
|
#import "TemporaryApp.h"
|
||||||
#import "HttpManager.h"
|
#import "HttpManager.h"
|
||||||
#import "Host.h"
|
#import "TemporaryHost.h"
|
||||||
|
|
||||||
@protocol AppAssetCallback <NSObject>
|
@protocol AppAssetCallback <NSObject>
|
||||||
|
|
||||||
- (void) receivedAssetForApp:(App*)app;
|
- (void) receivedAssetForApp:(TemporaryApp*)app;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface AppAssetManager : NSObject
|
@interface AppAssetManager : NSObject
|
||||||
|
|
||||||
- (id) initWithCallback:(id<AppAssetCallback>)callback;
|
- (id) initWithCallback:(id<AppAssetCallback>)callback;
|
||||||
- (void) retrieveAssetsFromHost:(Host*)host;
|
- (void) retrieveAssetsFromHost:(TemporaryHost*)host;
|
||||||
- (void) stopRetrieving;
|
- (void) stopRetrieving;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -28,8 +28,8 @@ static const int MAX_REQUEST_COUNT = 4;
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) retrieveAssetsFromHost:(Host*)host {
|
- (void) retrieveAssetsFromHost:(TemporaryHost*)host {
|
||||||
for (App* app in host.appList) {
|
for (TemporaryApp* app in host.appList) {
|
||||||
if (app.image == nil) {
|
if (app.image == nil) {
|
||||||
AppAssetRetriever* retriever = [[AppAssetRetriever alloc] init];
|
AppAssetRetriever* retriever = [[AppAssetRetriever alloc] init];
|
||||||
retriever.app = app;
|
retriever.app = app;
|
||||||
@@ -45,7 +45,7 @@ static const int MAX_REQUEST_COUNT = 4;
|
|||||||
[_opQueue cancelAllOperations];
|
[_opQueue cancelAllOperations];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) sendCallBackForApp:(App*)app {
|
- (void) sendCallBackForApp:(TemporaryApp*)app {
|
||||||
[_callback receivedAssetForApp:app];
|
[_callback receivedAssetForApp:app];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,14 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "Host.h"
|
#import "TemporaryHost.h"
|
||||||
#import "App.h"
|
#import "TemporaryApp.h"
|
||||||
#import "AppAssetManager.h"
|
#import "AppAssetManager.h"
|
||||||
|
|
||||||
@interface AppAssetRetriever : NSOperation
|
@interface AppAssetRetriever : NSOperation
|
||||||
|
|
||||||
@property (nonatomic) Host* host;
|
@property (nonatomic) TemporaryHost* host;
|
||||||
@property (nonatomic) App* app;
|
@property (nonatomic) TemporaryApp* app;
|
||||||
@property (nonatomic) id<AppAssetCallback> callback;
|
@property (nonatomic) id<AppAssetCallback> callback;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -36,7 +36,7 @@ static const int MAX_ATTEMPTS = 5;
|
|||||||
[self performSelectorOnMainThread:@selector(sendCallbackForApp:) withObject:self.app waitUntilDone:NO];
|
[self performSelectorOnMainThread:@selector(sendCallbackForApp:) withObject:self.app waitUntilDone:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) sendCallbackForApp:(App*)app {
|
- (void) sendCallbackForApp:(TemporaryApp*)app {
|
||||||
[self.callback receivedAssetForApp:app];
|
[self.callback receivedAssetForApp:app];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
@interface AppListResponse : NSObject <Response>
|
@interface AppListResponse : NSObject <Response>
|
||||||
|
|
||||||
- (void)populateWithData:(NSData *)data;
|
- (void)populateWithData:(NSData *)data;
|
||||||
- (NSArray*) getAppList;
|
- (NSSet*) getAppList;
|
||||||
- (BOOL) isStatusOk;
|
- (BOOL) isStatusOk;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
#import <libxml2/libxml/xmlreader.h>
|
#import <libxml2/libxml/xmlreader.h>
|
||||||
|
|
||||||
@implementation AppListResponse {
|
@implementation AppListResponse {
|
||||||
NSMutableArray* _appList;
|
NSMutableSet* _appList;
|
||||||
}
|
}
|
||||||
@synthesize data, statusCode, statusMessage;
|
@synthesize data, statusCode, statusMessage;
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ static const char* TAG_APP_IS_RUNNING = "IsRunning";
|
|||||||
|
|
||||||
- (void)populateWithData:(NSData *)xml {
|
- (void)populateWithData:(NSData *)xml {
|
||||||
self.data = xml;
|
self.data = xml;
|
||||||
_appList = [[NSMutableArray alloc] init];
|
_appList = [[NSMutableSet alloc] init];
|
||||||
[self parseData];
|
[self parseData];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ static const char* TAG_APP_IS_RUNNING = "IsRunning";
|
|||||||
xmlFreeDoc(docPtr);
|
xmlFreeDoc(docPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray*) getAppList {
|
- (NSSet*) getAppList {
|
||||||
return _appList;
|
return _appList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "MDNSManager.h"
|
#import "MDNSManager.h"
|
||||||
#import "Host.h"
|
#import "TemporaryHost.h"
|
||||||
|
|
||||||
@protocol DiscoveryCallback <NSObject>
|
@protocol DiscoveryCallback <NSObject>
|
||||||
|
|
||||||
@@ -22,8 +22,8 @@
|
|||||||
- (void) startDiscovery;
|
- (void) startDiscovery;
|
||||||
- (void) stopDiscovery;
|
- (void) stopDiscovery;
|
||||||
- (void) stopDiscoveryBlocking;
|
- (void) stopDiscoveryBlocking;
|
||||||
- (BOOL) addHostToDiscovery:(Host*)host;
|
- (BOOL) addHostToDiscovery:(TemporaryHost*)host;
|
||||||
- (void) removeHostFromDiscovery:(Host*)host;
|
- (void) removeHostFromDiscovery:(TemporaryHost*)host;
|
||||||
- (void) discoverHost:(NSString*)hostAddress withCallback:(void (^)(Host*, NSString*))callback;
|
- (void) discoverHost:(NSString*)hostAddress withCallback:(void (^)(TemporaryHost*, NSString*))callback;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
@implementation DiscoveryManager {
|
@implementation DiscoveryManager {
|
||||||
NSMutableArray* _hostQueue;
|
NSMutableArray* _hostQueue;
|
||||||
NSMutableArray* _discoveredHosts;
|
|
||||||
id<DiscoveryCallback> _callback;
|
id<DiscoveryCallback> _callback;
|
||||||
MDNSManager* _mdnsMan;
|
MDNSManager* _mdnsMan;
|
||||||
NSOperationQueue* _opQueue;
|
NSOperationQueue* _opQueue;
|
||||||
@@ -34,16 +33,10 @@
|
|||||||
_callback = callback;
|
_callback = callback;
|
||||||
shouldDiscover = NO;
|
shouldDiscover = NO;
|
||||||
_hostQueue = [NSMutableArray array];
|
_hostQueue = [NSMutableArray array];
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
for (TemporaryHost* host in hosts)
|
||||||
for (Host* host in hosts)
|
|
||||||
{
|
{
|
||||||
if (![self addHostToDiscovery:host])
|
[self addHostToDiscovery:host];
|
||||||
{
|
|
||||||
// Remove the duplicate host from the database
|
|
||||||
[dataMan removeHost:host];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
[dataMan saveData];
|
|
||||||
[_callback updateAllHosts:_hostQueue];
|
[_callback updateAllHosts:_hostQueue];
|
||||||
|
|
||||||
_opQueue = [[NSOperationQueue alloc] init];
|
_opQueue = [[NSOperationQueue alloc] init];
|
||||||
@@ -54,20 +47,18 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) discoverHost:(NSString *)hostAddress withCallback:(void (^)(Host *, NSString*))callback {
|
- (void) discoverHost:(NSString *)hostAddress withCallback:(void (^)(TemporaryHost *, NSString*))callback {
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddress uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddress uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||||
ServerInfoResponse* serverInfoResponse = [[ServerInfoResponse alloc] init];
|
ServerInfoResponse* serverInfoResponse = [[ServerInfoResponse alloc] init];
|
||||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResponse withUrlRequest:[hMan newServerInfoRequest] fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResponse withUrlRequest:[hMan newServerInfoRequest] fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
||||||
|
|
||||||
Host* host = nil;
|
TemporaryHost* host = nil;
|
||||||
if ([serverInfoResponse isStatusOk]) {
|
if ([serverInfoResponse isStatusOk]) {
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
host = [[TemporaryHost alloc] init];
|
||||||
host = [dataMan createHost];
|
|
||||||
host.activeAddress = host.address = hostAddress;
|
host.activeAddress = host.address = hostAddress;
|
||||||
host.online = YES;
|
host.online = YES;
|
||||||
[serverInfoResponse populateHost:host];
|
[serverInfoResponse populateHost:host];
|
||||||
if (![self addHostToDiscovery:host]) {
|
if (![self addHostToDiscovery:host]) {
|
||||||
[dataMan removeHost:host];
|
|
||||||
callback(nil, @"Host already added");
|
callback(nil, @"Host already added");
|
||||||
} else {
|
} else {
|
||||||
callback(host, nil);
|
callback(host, nil);
|
||||||
@@ -82,7 +73,7 @@
|
|||||||
Log(LOG_I, @"Starting discovery");
|
Log(LOG_I, @"Starting discovery");
|
||||||
shouldDiscover = YES;
|
shouldDiscover = YES;
|
||||||
[_mdnsMan searchForHosts];
|
[_mdnsMan searchForHosts];
|
||||||
for (Host* host in _hostQueue) {
|
for (TemporaryHost* host in _hostQueue) {
|
||||||
[_opQueue addOperation:[self createWorkerForHost:host]];
|
[_opQueue addOperation:[self createWorkerForHost:host]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,7 +94,7 @@
|
|||||||
Log(LOG_I, @"All discovery workers stopped");
|
Log(LOG_I, @"All discovery workers stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) addHostToDiscovery:(Host *)host {
|
- (BOOL) addHostToDiscovery:(TemporaryHost *)host {
|
||||||
if (host.uuid.length > 0 && ![self isHostInDiscovery:host]) {
|
if (host.uuid.length > 0 && ![self isHostInDiscovery:host]) {
|
||||||
[_hostQueue addObject:host];
|
[_hostQueue addObject:host];
|
||||||
if (shouldDiscover) {
|
if (shouldDiscover) {
|
||||||
@@ -114,7 +105,7 @@
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeHostFromDiscovery:(Host *)host {
|
- (void) removeHostFromDiscovery:(TemporaryHost *)host {
|
||||||
for (DiscoveryWorker* worker in [_opQueue operations]) {
|
for (DiscoveryWorker* worker in [_opQueue operations]) {
|
||||||
if ([worker getHost] == host) {
|
if ([worker getHost] == host) {
|
||||||
[worker cancel];
|
[worker cancel];
|
||||||
@@ -126,9 +117,8 @@
|
|||||||
// Override from MDNSCallback
|
// Override from MDNSCallback
|
||||||
- (void)updateHosts:(NSArray *)hosts {
|
- (void)updateHosts:(NSArray *)hosts {
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
|
||||||
// Discover the hosts before adding to eliminate duplicates
|
// Discover the hosts before adding to eliminate duplicates
|
||||||
for (Host* host in hosts) {
|
for (TemporaryHost* host in hosts) {
|
||||||
Log(LOG_I, @"Found host through MDNS: %@:", host.name);
|
Log(LOG_I, @"Found host through MDNS: %@:", host.name);
|
||||||
// Since this is on a background thread, we do not need to use the opQueue
|
// Since this is on a background thread, we do not need to use the opQueue
|
||||||
DiscoveryWorker* worker = (DiscoveryWorker*)[self createWorkerForHost:host];
|
DiscoveryWorker* worker = (DiscoveryWorker*)[self createWorkerForHost:host];
|
||||||
@@ -138,16 +128,14 @@
|
|||||||
[_callback updateAllHosts:_hostQueue];
|
[_callback updateAllHosts:_hostQueue];
|
||||||
} else {
|
} else {
|
||||||
Log(LOG_I, @"Not adding host to discovery: %@", host.name);
|
Log(LOG_I, @"Not adding host to discovery: %@", host.name);
|
||||||
[dataMan removeHost:host];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[dataMan saveData];
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) isHostInDiscovery:(Host*)host {
|
- (BOOL) isHostInDiscovery:(TemporaryHost*)host {
|
||||||
for (int i = 0; i < _hostQueue.count; i++) {
|
for (int i = 0; i < _hostQueue.count; i++) {
|
||||||
Host* discoveredHost = [_hostQueue objectAtIndex:i];
|
TemporaryHost* discoveredHost = [_hostQueue objectAtIndex:i];
|
||||||
if (discoveredHost.uuid.length > 0 && [discoveredHost.uuid isEqualToString:host.uuid]) {
|
if (discoveredHost.uuid.length > 0 && [discoveredHost.uuid isEqualToString:host.uuid]) {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
@@ -155,7 +143,7 @@
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSOperation*) createWorkerForHost:(Host*)host {
|
- (NSOperation*) createWorkerForHost:(TemporaryHost*)host {
|
||||||
DiscoveryWorker* worker = [[DiscoveryWorker alloc] initWithHost:host uniqueId:_uniqueId cert:_cert];
|
DiscoveryWorker* worker = [[DiscoveryWorker alloc] initWithHost:host uniqueId:_uniqueId cert:_cert];
|
||||||
return worker;
|
return worker;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,12 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "Host.h"
|
#import "TemporaryHost.h"
|
||||||
|
|
||||||
@interface DiscoveryWorker : NSOperation
|
@interface DiscoveryWorker : NSOperation
|
||||||
|
|
||||||
- (id) initWithHost:(Host*)host uniqueId:(NSString*)uniqueId cert:(NSData*)cert;
|
- (id) initWithHost:(TemporaryHost*)host uniqueId:(NSString*)uniqueId cert:(NSData*)cert;
|
||||||
- (void) discoverHost;
|
- (void) discoverHost;
|
||||||
- (Host*) getHost;
|
- (TemporaryHost*) getHost;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -11,16 +11,17 @@
|
|||||||
#import "HttpManager.h"
|
#import "HttpManager.h"
|
||||||
#import "ServerInfoResponse.h"
|
#import "ServerInfoResponse.h"
|
||||||
#import "HttpRequest.h"
|
#import "HttpRequest.h"
|
||||||
|
#import "DataManager.h"
|
||||||
|
|
||||||
@implementation DiscoveryWorker {
|
@implementation DiscoveryWorker {
|
||||||
Host* _host;
|
TemporaryHost* _host;
|
||||||
NSString* _uniqueId;
|
NSString* _uniqueId;
|
||||||
NSData* _cert;
|
NSData* _cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
||||||
|
|
||||||
- (id) initWithHost:(Host*)host uniqueId:(NSString*)uniqueId cert:(NSData*)cert {
|
- (id) initWithHost:(TemporaryHost*)host uniqueId:(NSString*)uniqueId cert:(NSData*)cert {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
_host = host;
|
_host = host;
|
||||||
_uniqueId = uniqueId;
|
_uniqueId = uniqueId;
|
||||||
@@ -28,7 +29,7 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (Host*) getHost {
|
- (TemporaryHost*) getHost {
|
||||||
return _host;
|
return _host;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +101,12 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
|||||||
ServerInfoResponse* serverInfoResp = [self requestInfoAtAddress:address];
|
ServerInfoResponse* serverInfoResp = [self requestInfoAtAddress:address];
|
||||||
receivedResponse = [self checkResponse:serverInfoResp];
|
receivedResponse = [self checkResponse:serverInfoResp];
|
||||||
if (receivedResponse) {
|
if (receivedResponse) {
|
||||||
|
[serverInfoResp populateHost:_host];
|
||||||
_host.activeAddress = address;
|
_host.activeAddress = address;
|
||||||
|
|
||||||
|
// Update the database using the response
|
||||||
|
DataManager *dataManager = [[DataManager alloc] init];
|
||||||
|
[dataManager updateHost:_host];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,7 +143,6 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
|||||||
if ([response isStatusOk]) {
|
if ([response isStatusOk]) {
|
||||||
// If the response is from a different host then do not update this host
|
// If the response is from a different host then do not update this host
|
||||||
if ((_host.uuid == nil || [[response getStringTag:TAG_UNIQUE_ID] isEqualToString:_host.uuid])) {
|
if ((_host.uuid == nil || [[response getStringTag:TAG_UNIQUE_ID] isEqualToString:_host.uuid])) {
|
||||||
[response populateHost:_host];
|
|
||||||
return YES;
|
return YES;
|
||||||
} else {
|
} else {
|
||||||
Log(LOG_I, @"Received response from incorrect host: %@ expected: %@", [response getStringTag:TAG_UNIQUE_ID], _host.uuid);
|
Log(LOG_I, @"Received response from incorrect host: %@ expected: %@", [response getStringTag:TAG_UNIQUE_ID], _host.uuid);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "Host.h"
|
|
||||||
#import "HttpResponse.h"
|
#import "HttpResponse.h"
|
||||||
#import "HttpRequest.h"
|
#import "HttpRequest.h"
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#import "HttpManager.h"
|
#import "HttpManager.h"
|
||||||
#import "HttpRequest.h"
|
#import "HttpRequest.h"
|
||||||
#import "CryptoManager.h"
|
#import "CryptoManager.h"
|
||||||
#import "App.h"
|
#import "TemporaryApp.h"
|
||||||
|
|
||||||
#include <libxml2/libxml/xmlreader.h>
|
#include <libxml2/libxml/xmlreader.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "Host.h"
|
|
||||||
|
|
||||||
static NSString* TAG_STATUS_CODE = @"status_code";
|
static NSString* TAG_STATUS_CODE = @"status_code";
|
||||||
static NSString* TAG_STATUS_MESSAGE = @"status_message";
|
static NSString* TAG_STATUS_MESSAGE = @"status_message";
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "HttpResponse.h"
|
#import "HttpResponse.h"
|
||||||
#import "App.h"
|
#import "TemporaryApp.h"
|
||||||
#import <libxml2/libxml/xmlreader.h>
|
#import <libxml2/libxml/xmlreader.h>
|
||||||
|
|
||||||
@implementation HttpResponse {
|
@implementation HttpResponse {
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "MDNSManager.h"
|
#import "MDNSManager.h"
|
||||||
#import "Host.h"
|
#import "TemporaryHost.h"
|
||||||
#import "DataManager.h"
|
|
||||||
|
|
||||||
@implementation MDNSManager {
|
@implementation MDNSManager {
|
||||||
NSNetServiceBrowser* mDNSBrowser;
|
NSNetServiceBrowser* mDNSBrowser;
|
||||||
@@ -47,10 +46,9 @@ static NSString* NV_SERVICE_TYPE = @"_nvstream._tcp";
|
|||||||
|
|
||||||
- (NSArray*) getFoundHosts {
|
- (NSArray*) getFoundHosts {
|
||||||
NSMutableArray* hosts = [[NSMutableArray alloc] init];
|
NSMutableArray* hosts = [[NSMutableArray alloc] init];
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
|
||||||
for (NSNetService* service in services) {
|
for (NSNetService* service in services) {
|
||||||
if (service.hostName != nil) {
|
if (service.hostName != nil) {
|
||||||
Host* host = [dataMan createHost];
|
TemporaryHost* host = [[TemporaryHost alloc] init];
|
||||||
host.activeAddress = host.address = service.hostName;
|
host.activeAddress = host.address = service.hostName;
|
||||||
host.name = host.address;
|
host.name = host.address;
|
||||||
[hosts addObject:host];
|
[hosts addObject:host];
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "HttpResponse.h"
|
#import "HttpResponse.h"
|
||||||
|
#import "TemporaryHost.h"
|
||||||
|
|
||||||
#define TAG_HOSTNAME @"hostname"
|
#define TAG_HOSTNAME @"hostname"
|
||||||
#define TAG_EXTERNAL_IP @"ExternalIP"
|
#define TAG_EXTERNAL_IP @"ExternalIP"
|
||||||
@@ -18,7 +19,7 @@
|
|||||||
@interface ServerInfoResponse : HttpResponse <Response>
|
@interface ServerInfoResponse : HttpResponse <Response>
|
||||||
|
|
||||||
- (void) populateWithData:(NSData *)data;
|
- (void) populateWithData:(NSData *)data;
|
||||||
- (void) populateHost:(Host*)host;
|
- (void) populateHost:(TemporaryHost*)host;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
[super parseData];
|
[super parseData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) populateHost:(Host*)host {
|
- (void) populateHost:(TemporaryHost*)host {
|
||||||
host.name = [[self getStringTag:TAG_HOSTNAME] trim];
|
host.name = [[self getStringTag:TAG_HOSTNAME] trim];
|
||||||
host.externalAddress = [[self getStringTag:TAG_EXTERNAL_IP] trim];
|
host.externalAddress = [[self getStringTag:TAG_EXTERNAL_IP] trim];
|
||||||
host.localAddress = [[self getStringTag:TAG_LOCAL_IP] trim];
|
host.localAddress = [[self getStringTag:TAG_LOCAL_IP] trim];
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "Host.h"
|
#import "TemporaryHost.h"
|
||||||
|
|
||||||
@interface WakeOnLanManager : NSObject
|
@interface WakeOnLanManager : NSObject
|
||||||
|
|
||||||
+ (void) wakeHost:(Host*)host;
|
+ (void) wakeHost:(TemporaryHost*)host;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
static const int numPorts = 5;
|
static const int numPorts = 5;
|
||||||
static const int ports[numPorts] = {7, 9, 47998, 47999, 48000};
|
static const int ports[numPorts] = {7, 9, 47998, 47999, 48000};
|
||||||
|
|
||||||
+ (void) wakeHost:(Host*)host {
|
+ (void) wakeHost:(TemporaryHost*)host {
|
||||||
NSData* wolPayload = [WakeOnLanManager createPayload:host];
|
NSData* wolPayload = [WakeOnLanManager createPayload:host];
|
||||||
CFDataRef dataPayload = CFDataCreate(kCFAllocatorDefault, [wolPayload bytes], [wolPayload length]);
|
CFDataRef dataPayload = CFDataCreate(kCFAllocatorDefault, [wolPayload bytes], [wolPayload length]);
|
||||||
CFSocketRef wolSocket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0, NULL, NULL);
|
CFSocketRef wolSocket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0, NULL, NULL);
|
||||||
@@ -56,7 +56,7 @@ static const int ports[numPorts] = {7, 9, 47998, 47999, 48000};
|
|||||||
CFRelease(dataPayload);
|
CFRelease(dataPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSData*) createPayload:(Host*)host {
|
+ (NSData*) createPayload:(TemporaryHost*)host {
|
||||||
NSMutableData* payload = [[NSMutableData alloc] initWithCapacity:102];
|
NSMutableData* payload = [[NSMutableData alloc] initWithCapacity:102];
|
||||||
|
|
||||||
// 6 bytes of FF
|
// 6 bytes of FF
|
||||||
|
|||||||
@@ -49,7 +49,6 @@
|
|||||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest]
|
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest]
|
||||||
fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
||||||
NSString* pairStatus = [serverInfoResp getStringTag:@"PairStatus"];
|
NSString* pairStatus = [serverInfoResp getStringTag:@"PairStatus"];
|
||||||
NSString* currentClient = [serverInfoResp getStringTag:@"CurrentClient"];
|
|
||||||
NSString* appversion = [serverInfoResp getStringTag:@"appversion"];
|
NSString* appversion = [serverInfoResp getStringTag:@"appversion"];
|
||||||
NSString* serverState = [serverInfoResp getStringTag:@"state"];
|
NSString* serverState = [serverInfoResp getStringTag:@"state"];
|
||||||
if (![serverInfoResp isStatusOk] || pairStatus == NULL || appversion == NULL || serverState == NULL) {
|
if (![serverInfoResp isStatusOk] || pairStatus == NULL || appversion == NULL || serverState == NULL) {
|
||||||
@@ -65,11 +64,6 @@
|
|||||||
|
|
||||||
// resumeApp and launchApp handle calling launchFailed
|
// resumeApp and launchApp handle calling launchFailed
|
||||||
if ([serverState hasSuffix:@"_SERVER_BUSY"]) {
|
if ([serverState hasSuffix:@"_SERVER_BUSY"]) {
|
||||||
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;
|
||||||
|
|||||||
@@ -7,17 +7,17 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import "App.h"
|
#import "TemporaryApp.h"
|
||||||
|
|
||||||
@protocol AppCallback <NSObject>
|
@protocol AppCallback <NSObject>
|
||||||
|
|
||||||
- (void) appClicked:(App*) app;
|
- (void) appClicked:(TemporaryApp*) app;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface UIAppView : UIView
|
@interface UIAppView : UIView
|
||||||
|
|
||||||
- (id) initWithApp:(App*)app cache:(NSCache*)cache andCallback:(id<AppCallback>)callback;
|
- (id) initWithApp:(TemporaryApp*)app cache:(NSCache*)cache andCallback:(id<AppCallback>)callback;
|
||||||
- (void) updateAppImage;
|
- (void) updateAppImage;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
#import "UIAppView.h"
|
#import "UIAppView.h"
|
||||||
|
|
||||||
@implementation UIAppView {
|
@implementation UIAppView {
|
||||||
App* _app;
|
TemporaryApp* _app;
|
||||||
UIButton* _appButton;
|
UIButton* _appButton;
|
||||||
UILabel* _appLabel;
|
UILabel* _appLabel;
|
||||||
UIImageView* _appOverlay;
|
UIImageView* _appOverlay;
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
static UIImage* noImage;
|
static UIImage* noImage;
|
||||||
|
|
||||||
- (id) initWithApp:(App*)app cache:(NSCache*)cache andCallback:(id<AppCallback>)callback {
|
- (id) initWithApp:(TemporaryApp*)app cache:(NSCache*)cache andCallback:(id<AppCallback>)callback {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
_app = app;
|
_app = app;
|
||||||
_callback = callback;
|
_callback = callback;
|
||||||
|
|||||||
@@ -7,19 +7,19 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import "Host.h"
|
#import "TemporaryHost.h"
|
||||||
|
|
||||||
@protocol HostCallback <NSObject>
|
@protocol HostCallback <NSObject>
|
||||||
|
|
||||||
- (void) hostClicked:(Host*)host view:(UIView*)view;
|
- (void) hostClicked:(TemporaryHost*)host view:(UIView*)view;
|
||||||
- (void) hostLongClicked:(Host*)host view:(UIView*)view;
|
- (void) hostLongClicked:(TemporaryHost*)host view:(UIView*)view;
|
||||||
- (void) addHostClicked;
|
- (void) addHostClicked;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface UIComputerView : UIView
|
@interface UIComputerView : UIView
|
||||||
|
|
||||||
- (id) initWithComputer:(Host*)host andCallback:(id<HostCallback>)callback;
|
- (id) initWithComputer:(TemporaryHost*)host andCallback:(id<HostCallback>)callback;
|
||||||
- (id) initForAddWithCallback:(id<HostCallback>)callback;
|
- (id) initForAddWithCallback:(id<HostCallback>)callback;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
#import "UIComputerView.h"
|
#import "UIComputerView.h"
|
||||||
|
|
||||||
@implementation UIComputerView {
|
@implementation UIComputerView {
|
||||||
Host* _host;
|
TemporaryHost* _host;
|
||||||
UIButton* _hostButton;
|
UIButton* _hostButton;
|
||||||
UILabel* _hostLabel;
|
UILabel* _hostLabel;
|
||||||
UILabel* _hostStatus;
|
UILabel* _hostStatus;
|
||||||
@@ -72,7 +72,7 @@ static const int LABEL_DY = 20;
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithComputer:(Host*)host andCallback:(id<HostCallback>)callback {
|
- (id) initWithComputer:(TemporaryHost*)host andCallback:(id<HostCallback>)callback {
|
||||||
self = [self init];
|
self = [self init];
|
||||||
_host = host;
|
_host = host;
|
||||||
_callback = callback;
|
_callback = callback;
|
||||||
@@ -123,7 +123,7 @@ static const int LABEL_DY = 20;
|
|||||||
self.frame = CGRectMake(x, y, width, height);
|
self.frame = CGRectMake(x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) updateContentsForHost:(Host*)host {
|
- (void) updateContentsForHost:(TemporaryHost*)host {
|
||||||
_hostLabel.text = _host.name;
|
_hostLabel.text = _host.name;
|
||||||
_hostLabel.textColor = [UIColor whiteColor];
|
_hostLabel.textColor = [UIColor whiteColor];
|
||||||
[_hostLabel sizeToFit];
|
[_hostLabel sizeToFit];
|
||||||
|
|||||||
@@ -15,10 +15,9 @@
|
|||||||
#import "Utils.h"
|
#import "Utils.h"
|
||||||
#import "UIComputerView.h"
|
#import "UIComputerView.h"
|
||||||
#import "UIAppView.h"
|
#import "UIAppView.h"
|
||||||
#import "App.h"
|
|
||||||
#import "SettingsViewController.h"
|
#import "SettingsViewController.h"
|
||||||
#import "DataManager.h"
|
#import "DataManager.h"
|
||||||
#import "Settings.h"
|
#import "TemporarySettings.h"
|
||||||
#import "WakeOnLanManager.h"
|
#import "WakeOnLanManager.h"
|
||||||
#import "AppListResponse.h"
|
#import "AppListResponse.h"
|
||||||
#import "ServerInfoResponse.h"
|
#import "ServerInfoResponse.h"
|
||||||
@@ -30,7 +29,7 @@
|
|||||||
|
|
||||||
@implementation MainFrameViewController {
|
@implementation MainFrameViewController {
|
||||||
NSOperationQueue* _opQueue;
|
NSOperationQueue* _opQueue;
|
||||||
Host* _selectedHost;
|
TemporaryHost* _selectedHost;
|
||||||
NSString* _uniqueId;
|
NSString* _uniqueId;
|
||||||
NSData* _cert;
|
NSData* _cert;
|
||||||
DiscoveryManager* _discMan;
|
DiscoveryManager* _discMan;
|
||||||
@@ -80,7 +79,7 @@ static NSMutableSet* hostList;
|
|||||||
|
|
||||||
// Capture the host here because it can change once we
|
// Capture the host here because it can change once we
|
||||||
// leave the main thread
|
// leave the main thread
|
||||||
Host* host = _selectedHost;
|
TemporaryHost* host = _selectedHost;
|
||||||
|
|
||||||
if ([host.appList count] > 0) {
|
if ([host.appList count] > 0) {
|
||||||
usingCachedAppList = true;
|
usingCachedAppList = true;
|
||||||
@@ -141,7 +140,7 @@ static NSMutableSet* hostList;
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[self mergeAppLists:[appListResp getAppList] forHost:host];
|
[self updateApplist:[appListResp getAppList] forHost:host];
|
||||||
|
|
||||||
if (host != _selectedHost) {
|
if (host != _selectedHost) {
|
||||||
return;
|
return;
|
||||||
@@ -159,11 +158,12 @@ static NSMutableSet* hostList;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) mergeAppLists:(NSArray*) newList forHost:(Host*)host {
|
- (void) updateApplist:(NSSet*) newList forHost:(TemporaryHost*)host {
|
||||||
DataManager* database = [[DataManager alloc] init];
|
DataManager* database = [[DataManager alloc] init];
|
||||||
|
|
||||||
for (TemporaryApp* app in newList) {
|
for (TemporaryApp* app in newList) {
|
||||||
BOOL appAlreadyInList = NO;
|
BOOL appAlreadyInList = NO;
|
||||||
for (App* savedApp in host.appList) {
|
for (TemporaryApp* savedApp in host.appList) {
|
||||||
if ([app.id isEqualToString:savedApp.id]) {
|
if ([app.id isEqualToString:savedApp.id]) {
|
||||||
savedApp.name = app.name;
|
savedApp.name = app.name;
|
||||||
savedApp.isRunning = app.isRunning;
|
savedApp.isRunning = app.isRunning;
|
||||||
@@ -173,7 +173,7 @@ static NSMutableSet* hostList;
|
|||||||
}
|
}
|
||||||
if (!appAlreadyInList) {
|
if (!appAlreadyInList) {
|
||||||
app.host = host;
|
app.host = host;
|
||||||
[database addAppFromTemporaryApp:app];
|
[host.appList addObject:app];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,9 +181,9 @@ static NSMutableSet* hostList;
|
|||||||
do {
|
do {
|
||||||
appWasRemoved = NO;
|
appWasRemoved = NO;
|
||||||
|
|
||||||
for (App* app in host.appList) {
|
for (TemporaryApp* app in host.appList) {
|
||||||
appWasRemoved = YES;
|
appWasRemoved = YES;
|
||||||
for (App* mergedApp in newList) {
|
for (TemporaryApp* mergedApp in newList) {
|
||||||
if ([mergedApp.id isEqualToString:app.id]) {
|
if ([mergedApp.id isEqualToString:app.id]) {
|
||||||
appWasRemoved = NO;
|
appWasRemoved = NO;
|
||||||
break;
|
break;
|
||||||
@@ -192,7 +192,14 @@ static NSMutableSet* hostList;
|
|||||||
if (appWasRemoved) {
|
if (appWasRemoved) {
|
||||||
// Removing the app mutates the list we're iterating (which isn't legal).
|
// Removing the app mutates the list we're iterating (which isn't legal).
|
||||||
// We need to jump out of this loop and restart enumeration.
|
// We need to jump out of this loop and restart enumeration.
|
||||||
[database removeAppFromHost:app];
|
|
||||||
|
[host.appList removeObject:app];
|
||||||
|
|
||||||
|
// It's important to remove the app record from the database
|
||||||
|
// since we'll have a constraint violation now that appList
|
||||||
|
// doesn't have this app in it.
|
||||||
|
[database removeApp:app];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,23 +207,25 @@ static NSMutableSet* hostList;
|
|||||||
// Keep looping until the list is no longer being mutated
|
// Keep looping until the list is no longer being mutated
|
||||||
} while (appWasRemoved);
|
} while (appWasRemoved);
|
||||||
|
|
||||||
[database saveData];
|
[database updateAppsForExistingHost:host];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showHostSelectionView {
|
- (void)showHostSelectionView {
|
||||||
[_appManager stopRetrieving];
|
[_appManager stopRetrieving];
|
||||||
[[[DataManager alloc] init] saveData];
|
|
||||||
_selectedHost = nil;
|
_selectedHost = nil;
|
||||||
_computerNameButton.title = @"No Host Selected";
|
_computerNameButton.title = @"No Host Selected";
|
||||||
[self.collectionView reloadData];
|
[self.collectionView reloadData];
|
||||||
[self.view addSubview:hostScrollView];
|
[self.view addSubview:hostScrollView];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) receivedAssetForApp:(App*)app {
|
- (void) receivedAssetForApp:(TemporaryApp*)app {
|
||||||
// Update the box art cache now so we don't have to do it
|
// Update the box art cache now so we don't have to do it
|
||||||
// on the main thread
|
// on the main thread
|
||||||
[self updateBoxArtCacheForApp:app];
|
[self updateBoxArtCacheForApp:app];
|
||||||
|
|
||||||
|
DataManager* dataManager = [[DataManager alloc] init];
|
||||||
|
[dataManager updateIconForExistingApp: app];
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[self.collectionView reloadData];
|
[self.collectionView reloadData];
|
||||||
});
|
});
|
||||||
@@ -230,7 +239,7 @@ static NSMutableSet* hostList;
|
|||||||
[self presentViewController:alert animated:YES completion:nil];
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) hostClicked:(Host *)host view:(UIView *)view {
|
- (void) hostClicked:(TemporaryHost *)host view:(UIView *)view {
|
||||||
// Treat clicks on offline hosts to be long clicks
|
// Treat clicks on offline hosts to be long clicks
|
||||||
// This shows the context menu with wake, delete, etc. rather
|
// This shows the context menu with wake, delete, etc. rather
|
||||||
// than just hanging for a while and failing as we would in this
|
// than just hanging for a while and failing as we would in this
|
||||||
@@ -296,7 +305,7 @@ static NSMutableSet* hostList;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)hostLongClicked:(Host *)host view:(UIView *)view {
|
- (void)hostLongClicked:(TemporaryHost *)host view:(UIView *)view {
|
||||||
Log(LOG_D, @"Long clicked host: %@", host.name);
|
Log(LOG_D, @"Long clicked host: %@", host.name);
|
||||||
UIAlertController* longClickAlert = [UIAlertController alertControllerWithTitle:host.name message:@"" preferredStyle:UIAlertControllerStyleActionSheet];
|
UIAlertController* longClickAlert = [UIAlertController alertControllerWithTitle:host.name message:@"" preferredStyle:UIAlertControllerStyleActionSheet];
|
||||||
if (!host.online) {
|
if (!host.online) {
|
||||||
@@ -322,8 +331,8 @@ static NSMutableSet* hostList;
|
|||||||
[dataMan removeHost:host];
|
[dataMan removeHost:host];
|
||||||
@synchronized(hostList) {
|
@synchronized(hostList) {
|
||||||
[hostList removeObject:host];
|
[hostList removeObject:host];
|
||||||
|
[self updateAllHosts:[hostList allObjects]];
|
||||||
}
|
}
|
||||||
[self updateAllHosts:[hostList allObjects]];
|
|
||||||
|
|
||||||
}]];
|
}]];
|
||||||
[longClickAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
|
[longClickAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
|
||||||
@@ -345,10 +354,8 @@ static NSMutableSet* hostList;
|
|||||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||||
NSString* hostAddress = ((UITextField*)[[alertController textFields] objectAtIndex:0]).text;
|
NSString* hostAddress = ((UITextField*)[[alertController textFields] objectAtIndex:0]).text;
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||||
[_discMan discoverHost:hostAddress withCallback:^(Host* host, NSString* error){
|
[_discMan discoverHost:hostAddress withCallback:^(TemporaryHost* host, NSString* error){
|
||||||
if (host != nil) {
|
if (host != nil) {
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
|
||||||
[dataMan saveData];
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
@synchronized(hostList) {
|
@synchronized(hostList) {
|
||||||
[hostList addObject:host];
|
[hostList addObject:host];
|
||||||
@@ -369,14 +376,14 @@ static NSMutableSet* hostList;
|
|||||||
[self presentViewController:alertController animated:YES completion:nil];
|
[self presentViewController:alertController animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) appClicked:(App *)app {
|
- (void) appClicked:(TemporaryApp *)app {
|
||||||
Log(LOG_D, @"Clicked app: %@", app.name);
|
Log(LOG_D, @"Clicked app: %@", app.name);
|
||||||
_streamConfig = [[StreamConfiguration alloc] init];
|
_streamConfig = [[StreamConfiguration alloc] init];
|
||||||
_streamConfig.host = app.host.activeAddress;
|
_streamConfig.host = app.host.activeAddress;
|
||||||
_streamConfig.appID = app.id;
|
_streamConfig.appID = app.id;
|
||||||
|
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
Settings* streamSettings = [dataMan retrieveSettings];
|
TemporarySettings* streamSettings = [dataMan getSettings];
|
||||||
|
|
||||||
_streamConfig.frameRate = [streamSettings.framerate intValue];
|
_streamConfig.frameRate = [streamSettings.framerate intValue];
|
||||||
_streamConfig.bitRate = [streamSettings.bitrate intValue];
|
_streamConfig.bitRate = [streamSettings.bitrate intValue];
|
||||||
@@ -389,7 +396,7 @@ static NSMutableSet* hostList;
|
|||||||
[[self revealViewController] revealToggle:self];
|
[[self revealViewController] revealToggle:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
App* currentApp = [self findRunningApp:app.host];
|
TemporaryApp* currentApp = [self findRunningApp:app.host];
|
||||||
if (currentApp != nil) {
|
if (currentApp != nil) {
|
||||||
UIAlertController* alertController = [UIAlertController
|
UIAlertController* alertController = [UIAlertController
|
||||||
alertControllerWithTitle: app.name
|
alertControllerWithTitle: app.name
|
||||||
@@ -455,8 +462,8 @@ static NSMutableSet* hostList;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (App*) findRunningApp:(Host*)host {
|
- (TemporaryApp*) findRunningApp:(TemporaryHost*)host {
|
||||||
for (App* app in host.appList) {
|
for (TemporaryApp* app in host.appList) {
|
||||||
if (app.isRunning) {
|
if (app.isRunning) {
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
@@ -593,19 +600,16 @@ static NSMutableSet* hostList;
|
|||||||
|
|
||||||
// Purge the box art cache
|
// Purge the box art cache
|
||||||
[_boxArtCache removeAllObjects];
|
[_boxArtCache removeAllObjects];
|
||||||
|
|
||||||
// In case the host objects were updated in the background
|
|
||||||
[[[DataManager alloc] init] saveData];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) retrieveSavedHosts {
|
- (void) retrieveSavedHosts {
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
NSArray* hosts = [dataMan retrieveHosts];
|
NSArray* hosts = [dataMan getHosts];
|
||||||
@synchronized(hostList) {
|
@synchronized(hostList) {
|
||||||
[hostList addObjectsFromArray:hosts];
|
[hostList addObjectsFromArray:hosts];
|
||||||
|
|
||||||
// Initialize the non-persistent host state
|
// Initialize the non-persistent host state
|
||||||
for (Host* host in hostList) {
|
for (TemporaryHost* host in hostList) {
|
||||||
if (host.activeAddress == nil) {
|
if (host.activeAddress == nil) {
|
||||||
host.activeAddress = host.localAddress;
|
host.activeAddress = host.localAddress;
|
||||||
}
|
}
|
||||||
@@ -622,7 +626,7 @@ static NSMutableSet* hostList;
|
|||||||
- (void) updateAllHosts:(NSArray *)hosts {
|
- (void) updateAllHosts:(NSArray *)hosts {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
Log(LOG_D, @"New host list:");
|
Log(LOG_D, @"New host list:");
|
||||||
for (Host* host in hosts) {
|
for (TemporaryHost* host in hosts) {
|
||||||
Log(LOG_D, @"Host: \n{\n\t name:%@ \n\t address:%@ \n\t localAddress:%@ \n\t externalAddress:%@ \n\t uuid:%@ \n\t mac:%@ \n\t pairState:%d \n\t online:%d \n\t activeAddress:%@ \n}", host.name, host.address, host.localAddress, host.externalAddress, host.uuid, host.mac, host.pairState, host.online, host.activeAddress);
|
Log(LOG_D, @"Host: \n{\n\t name:%@ \n\t address:%@ \n\t localAddress:%@ \n\t externalAddress:%@ \n\t uuid:%@ \n\t mac:%@ \n\t pairState:%d \n\t online:%d \n\t activeAddress:%@ \n}", host.name, host.address, host.localAddress, host.externalAddress, host.uuid, host.mac, host.pairState, host.online, host.activeAddress);
|
||||||
}
|
}
|
||||||
@synchronized(hostList) {
|
@synchronized(hostList) {
|
||||||
@@ -642,7 +646,7 @@ static NSMutableSet* hostList;
|
|||||||
@synchronized (hostList) {
|
@synchronized (hostList) {
|
||||||
// Sort the host list in alphabetical order
|
// Sort the host list in alphabetical order
|
||||||
NSArray* sortedHostList = [[hostList allObjects] sortedArrayUsingSelector:@selector(compareName:)];
|
NSArray* sortedHostList = [[hostList allObjects] sortedArrayUsingSelector:@selector(compareName:)];
|
||||||
for (Host* comp in sortedHostList) {
|
for (TemporaryHost* comp in sortedHostList) {
|
||||||
compView = [[UIComputerView alloc] initWithComputer:comp andCallback:self];
|
compView = [[UIComputerView alloc] initWithComputer:comp andCallback:self];
|
||||||
compView.center = CGPointMake([self getCompViewX:compView addComp:addComp prevEdge:prevEdge], hostScrollView.frame.size.height / 2);
|
compView.center = CGPointMake([self getCompViewX:compView addComp:addComp prevEdge:prevEdge], hostScrollView.frame.size.height / 2);
|
||||||
prevEdge = compView.frame.origin.x + compView.frame.size.width;
|
prevEdge = compView.frame.origin.x + compView.frame.size.width;
|
||||||
@@ -667,7 +671,7 @@ static NSMutableSet* hostList;
|
|||||||
|
|
||||||
// This function forces immediate decoding of the UIImage, rather
|
// This function forces immediate decoding of the UIImage, rather
|
||||||
// than the default lazy decoding that results in janky scrolling.
|
// than the default lazy decoding that results in janky scrolling.
|
||||||
+ (UIImage*) loadBoxArtForCaching:(App*)app {
|
+ (UIImage*) loadBoxArtForCaching:(TemporaryApp*)app {
|
||||||
|
|
||||||
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)app.image, NULL);
|
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)app.image, NULL);
|
||||||
CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, (__bridge CFDictionaryRef)@{(id)kCGImageSourceShouldCacheImmediately: (id)kCFBooleanTrue});
|
CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, (__bridge CFDictionaryRef)@{(id)kCGImageSourceShouldCacheImmediately: (id)kCFBooleanTrue});
|
||||||
@@ -680,7 +684,7 @@ static NSMutableSet* hostList;
|
|||||||
return boxArt;
|
return boxArt;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) updateBoxArtCacheForApp:(App*)app {
|
- (void) updateBoxArtCacheForApp:(TemporaryApp*)app {
|
||||||
if (app.image == nil) {
|
if (app.image == nil) {
|
||||||
[_boxArtCache removeObjectForKey:app];
|
[_boxArtCache removeObjectForKey:app];
|
||||||
}
|
}
|
||||||
@@ -689,7 +693,7 @@ static NSMutableSet* hostList;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) updateAppsForHost:(Host*)host {
|
- (void) updateAppsForHost:(TemporaryHost*)host {
|
||||||
if (host != _selectedHost) {
|
if (host != _selectedHost) {
|
||||||
Log(LOG_W, @"Mismatched host during app update");
|
Log(LOG_W, @"Mismatched host during app update");
|
||||||
return;
|
return;
|
||||||
@@ -715,12 +719,12 @@ static NSMutableSet* hostList;
|
|||||||
|
|
||||||
// Start 2 jobs
|
// Start 2 jobs
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
for (App* app in firstHalf) {
|
for (TemporaryApp* app in firstHalf) {
|
||||||
[self updateBoxArtCacheForApp:app];
|
[self updateBoxArtCacheForApp:app];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
for (App* app in secondHalf) {
|
for (TemporaryApp* app in secondHalf) {
|
||||||
[self updateBoxArtCacheForApp:app];
|
[self updateBoxArtCacheForApp:app];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -732,7 +736,7 @@ static NSMutableSet* hostList;
|
|||||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
UICollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AppCell" forIndexPath:indexPath];
|
UICollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AppCell" forIndexPath:indexPath];
|
||||||
|
|
||||||
App* app = _sortedAppList[indexPath.row];
|
TemporaryApp* app = _sortedAppList[indexPath.row];
|
||||||
UIAppView* appView = [[UIAppView alloc] initWithApp:app cache:_boxArtCache andCallback:self];
|
UIAppView* appView = [[UIAppView alloc] initWithApp:app cache:_boxArtCache andCallback:self];
|
||||||
[appView updateAppImage];
|
[appView updateAppImage];
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "SettingsViewController.h"
|
#import "SettingsViewController.h"
|
||||||
#import "Settings.h"
|
#import "TemporarySettings.h"
|
||||||
#import "DataManager.h"
|
#import "DataManager.h"
|
||||||
|
|
||||||
#define BITRATE_INTERVAL 500 // in kbps
|
#define BITRATE_INTERVAL 500 // in kbps
|
||||||
@@ -22,7 +22,7 @@ static NSString* bitrateFormat = @"Bitrate: %.1f Mbps";
|
|||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
Settings* currentSettings = [dataMan retrieveSettings];
|
TemporarySettings* currentSettings = [dataMan getSettings];
|
||||||
|
|
||||||
// Bitrate is persisted in kbps
|
// Bitrate is persisted in kbps
|
||||||
_bitrate = [currentSettings.bitrate integerValue];
|
_bitrate = [currentSettings.bitrate integerValue];
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
9832D1361BBCD5C50036EF48 /* TemporaryApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 9832D1351BBCD5C50036EF48 /* TemporaryApp.m */; };
|
9832D1361BBCD5C50036EF48 /* TemporaryApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 9832D1351BBCD5C50036EF48 /* TemporaryApp.m */; };
|
||||||
987140041B04542F00AB57D5 /* libmoonlight-common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB1E43101AE8B0F200AFF679 /* libmoonlight-common.a */; };
|
987140041B04542F00AB57D5 /* libmoonlight-common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB1E43101AE8B0F200AFF679 /* libmoonlight-common.a */; };
|
||||||
|
98D5856D1C0EA79600F6CC00 /* TemporaryHost.m in Sources */ = {isa = PBXBuildFile; fileRef = 98D5856C1C0EA79600F6CC00 /* TemporaryHost.m */; };
|
||||||
|
98D585701C0ED0E800F6CC00 /* TemporarySettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 98D5856F1C0ED0E800F6CC00 /* TemporarySettings.m */; };
|
||||||
9E5D600B1A5A5A3900689918 /* Apache License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D5FF81A5A5A3900689918 /* Apache License.txt */; };
|
9E5D600B1A5A5A3900689918 /* Apache License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D5FF81A5A5A3900689918 /* Apache License.txt */; };
|
||||||
9E5D600C1A5A5A3900689918 /* Roboto-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D5FF91A5A5A3900689918 /* Roboto-Black.ttf */; };
|
9E5D600C1A5A5A3900689918 /* Roboto-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D5FF91A5A5A3900689918 /* Roboto-Black.ttf */; };
|
||||||
9E5D600E1A5A5A3900689918 /* Roboto-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D5FFB1A5A5A3900689918 /* Roboto-Bold.ttf */; };
|
9E5D600E1A5A5A3900689918 /* Roboto-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D5FFB1A5A5A3900689918 /* Roboto-Bold.ttf */; };
|
||||||
@@ -98,6 +100,10 @@
|
|||||||
9832D1341BBCD5C50036EF48 /* TemporaryApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporaryApp.h; path = Database/TemporaryApp.h; sourceTree = "<group>"; };
|
9832D1341BBCD5C50036EF48 /* TemporaryApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporaryApp.h; path = Database/TemporaryApp.h; sourceTree = "<group>"; };
|
||||||
9832D1351BBCD5C50036EF48 /* TemporaryApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporaryApp.m; path = Database/TemporaryApp.m; sourceTree = "<group>"; };
|
9832D1351BBCD5C50036EF48 /* TemporaryApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporaryApp.m; path = Database/TemporaryApp.m; sourceTree = "<group>"; };
|
||||||
98A03B4519F3514B00861ACA /* moonlight-common.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "moonlight-common.xcodeproj"; path = "limelight-common-c/moonlight-common.xcodeproj"; sourceTree = "<group>"; };
|
98A03B4519F3514B00861ACA /* moonlight-common.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "moonlight-common.xcodeproj"; path = "limelight-common-c/moonlight-common.xcodeproj"; sourceTree = "<group>"; };
|
||||||
|
98D5856B1C0EA79600F6CC00 /* TemporaryHost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporaryHost.h; path = Database/TemporaryHost.h; sourceTree = "<group>"; };
|
||||||
|
98D5856C1C0EA79600F6CC00 /* TemporaryHost.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporaryHost.m; path = Database/TemporaryHost.m; sourceTree = "<group>"; };
|
||||||
|
98D5856E1C0ED0E800F6CC00 /* TemporarySettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporarySettings.h; path = Database/TemporarySettings.h; sourceTree = "<group>"; };
|
||||||
|
98D5856F1C0ED0E800F6CC00 /* TemporarySettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporarySettings.m; path = Database/TemporarySettings.m; sourceTree = "<group>"; };
|
||||||
9E5D5FF81A5A5A3900689918 /* Apache License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Apache License.txt"; sourceTree = "<group>"; };
|
9E5D5FF81A5A5A3900689918 /* Apache License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Apache License.txt"; sourceTree = "<group>"; };
|
||||||
9E5D5FF91A5A5A3900689918 /* Roboto-Black.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Black.ttf"; sourceTree = "<group>"; };
|
9E5D5FF91A5A5A3900689918 /* Roboto-Black.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Black.ttf"; sourceTree = "<group>"; };
|
||||||
9E5D5FFB1A5A5A3900689918 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Bold.ttf"; sourceTree = "<group>"; };
|
9E5D5FFB1A5A5A3900689918 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Bold.ttf"; sourceTree = "<group>"; };
|
||||||
@@ -733,6 +739,10 @@
|
|||||||
FBD349611A0089F6002D2A60 /* DataManager.m */,
|
FBD349611A0089F6002D2A60 /* DataManager.m */,
|
||||||
9832D1341BBCD5C50036EF48 /* TemporaryApp.h */,
|
9832D1341BBCD5C50036EF48 /* TemporaryApp.h */,
|
||||||
9832D1351BBCD5C50036EF48 /* TemporaryApp.m */,
|
9832D1351BBCD5C50036EF48 /* TemporaryApp.m */,
|
||||||
|
98D5856B1C0EA79600F6CC00 /* TemporaryHost.h */,
|
||||||
|
98D5856C1C0EA79600F6CC00 /* TemporaryHost.m */,
|
||||||
|
98D5856E1C0ED0E800F6CC00 /* TemporarySettings.h */,
|
||||||
|
98D5856F1C0ED0E800F6CC00 /* TemporarySettings.m */,
|
||||||
);
|
);
|
||||||
name = Database;
|
name = Database;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -855,11 +865,13 @@
|
|||||||
FB89462D19F646E200339C8A /* MDNSManager.m in Sources */,
|
FB89462D19F646E200339C8A /* MDNSManager.m in Sources */,
|
||||||
FB89462B19F646E200339C8A /* StreamView.m in Sources */,
|
FB89462B19F646E200339C8A /* StreamView.m in Sources */,
|
||||||
FB4678FA1A55FFAD00377732 /* DiscoveryManager.m in Sources */,
|
FB4678FA1A55FFAD00377732 /* DiscoveryManager.m in Sources */,
|
||||||
|
98D5856D1C0EA79600F6CC00 /* TemporaryHost.m in Sources */,
|
||||||
FB89463519F646E200339C8A /* MainFrameViewController.m in Sources */,
|
FB89463519F646E200339C8A /* MainFrameViewController.m in Sources */,
|
||||||
FBD1C8E21A8AD71400C6703C /* Logger.m in Sources */,
|
FBD1C8E21A8AD71400C6703C /* Logger.m in Sources */,
|
||||||
FB1D599A1BBCCD7E00F482CA /* AppCollectionView.m in Sources */,
|
FB1D599A1BBCCD7E00F482CA /* AppCollectionView.m in Sources */,
|
||||||
FB89463619F646E200339C8A /* StreamFrameViewController.m in Sources */,
|
FB89463619F646E200339C8A /* StreamFrameViewController.m in Sources */,
|
||||||
9832D1361BBCD5C50036EF48 /* TemporaryApp.m in Sources */,
|
9832D1361BBCD5C50036EF48 /* TemporaryApp.m in Sources */,
|
||||||
|
98D585701C0ED0E800F6CC00 /* TemporarySettings.m in Sources */,
|
||||||
FB89462819F646E200339C8A /* CryptoManager.m in Sources */,
|
FB89462819F646E200339C8A /* CryptoManager.m in Sources */,
|
||||||
FB89462E19F646E200339C8A /* PairManager.m in Sources */,
|
FB89462E19F646E200339C8A /* PairManager.m in Sources */,
|
||||||
FB9AFD371A7E02DB00872C98 /* HttpRequest.m in Sources */,
|
FB9AFD371A7E02DB00872C98 /* HttpRequest.m in Sources */,
|
||||||
|
|||||||
@@ -2,7 +2,13 @@
|
|||||||
|
|
||||||
#### Now available on the [App Store](https://itunes.apple.com/us/app/moonlight-game-streaming/id1000551566?mt=8)
|
#### Now available on the [App Store](https://itunes.apple.com/us/app/moonlight-game-streaming/id1000551566?mt=8)
|
||||||
|
|
||||||
[Moonlight](https://github.com/moonlight-stream) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield, but built for iOS. Moonlight iOS allows you to stream your full collection of Steam games from
|
[Moonlight](http://moonlight-stream.com) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield, but built for iOS. Moonlight iOS allows you to stream your full collection of Steam games from
|
||||||
your powerful desktop computer to your iOS Device.
|
your powerful desktop computer to your iOS Device.
|
||||||
|
|
||||||
There are also versions for [Android](https://github.com/moonlight-stream/moonlight-android) and [PC](https://github.com/moonlight-stream/moonlight-pc).
|
There are also versions for [Android](https://github.com/moonlight-stream/moonlight-android) and [PC](https://github.com/moonlight-stream/moonlight-pc).
|
||||||
|
|
||||||
|
##### Apple TV Note:
|
||||||
|
We current cannot write a port for Apple TV due to a limitation in the tvOS SDK that prevents Moonlight from using the APIs that would be necessary for it to work. Thank you for your interest - you can track this issue [here](https://github.com/moonlight-stream/moonlight-ios/issues/184).
|
||||||
|
|
||||||
|
##### Questions?
|
||||||
|
Check out our [wiki](https://github.com/moonlight-stream/moonlight-android/wiki).
|
||||||
+1
-1
Submodule limelight-common-c updated: 349d1baa53...04b00f9e8a.
Reference in new issue
Block a user