Commit 58140641 authored by Pierre SAGASPE's avatar Pierre SAGASPE

apple tv : Add UI to connect manually to SMB / FTP / PLEX server (#105)

parent 2fbe82e0
#import "VLCTVConstants.h"
#import <TVVLCKit/TVVLCKit.h>
#import "VLCNetworkServerLoginInformation.h"
#import "VLCNetworkServerLoginInformation+Keychain.h"
#import "VLCNetworkServerBrowserPlex.h"
#import "VLCNetworkServerBrowserVLCMedia.h"
#import "VLCNetworkServerBrowserFTP.h"
#import "VLCLocalNetworkServiceBrowserPlex.h"
#import "VLCLocalNetworkServiceBrowserFTP.h"
#import "VLCLocalNetworkServiceBrowserDSM.h"
#import "VLCServerListTVViewController.h"
#import "VLCSearchableServerBrowsingTVViewController.h"
#import <XKKeychain/XKKeychainGenericPasswordItem.h>
/*****************************************************************************
* VLCNetworkLoginTVViewController.swift
* VLC for iOS
*****************************************************************************
* Copyright (c) 2019 VideoLAN. All rights reserved.
* $Id$
*
* Authors: Pierre Sagaspe <pierre.sagaspe # me.com>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
import UIKit
@objc class VLCNetworkLoginTVViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UIGestureRecognizerDelegate {
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBOutlet weak var serverField: UITextField!
@IBOutlet weak var portField: UITextField!
@IBOutlet weak var usernameField: UITextField!
@IBOutlet weak var passwordField: UITextField!
@IBOutlet weak var workgroupField: UITextField!
@IBOutlet weak var buttonConnect: UIButton!
@IBOutlet weak var buttonSave: UIButton!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var nothingFoundView: UIView!
@IBOutlet weak var nothingFoundLabel: UILabel!
var serverList: NSMutableArray!
override func viewDidLoad() {
super.viewDidLoad()
configureAppreance()
serverList = NSMutableArray.init()
NotificationCenter.default.addObserver(self,
selector: #selector(ubiquitousKeyValueStoreDidChange),
name: NSUbiquitousKeyValueStore.didChangeExternallyNotification,
object: NSUbiquitousKeyValueStore.default)
segmentedControl.addTarget(self, action: #selector(segmentedControlChanged), for: .valueChanged)
let ukvStore = NSUbiquitousKeyValueStore.default
ukvStore.synchronize()
let ukvServerList = ukvStore.array(forKey: kVLCStoredServerList)
if ukvServerList != nil {
serverList.addObjects(from: ukvServerList!)
}
let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
longPressGestureRecognizer.minimumPressDuration = 1
longPressGestureRecognizer.delaysTouchesBegan = true
longPressGestureRecognizer.delegate = self
tableView.addGestureRecognizer(longPressGestureRecognizer)
tableView.dataSource = self
tableView.delegate = self
}
func configureAppreance() {
segmentedControl.setTitle(NSLocalizedString("SMB_CIFS_FILE_SERVERS_SHORT", comment: ""), forSegmentAt: 0)
segmentedControl.setTitle(NSLocalizedString("FTP_SHORT", comment: ""), forSegmentAt: 1)
segmentedControl.setTitle(NSLocalizedString("PLEX_SHORT", comment: ""), forSegmentAt: 2)
setSegControlProtocolIdentifier(VLCNetworkServerProtocolIdentifierFTP)
serverField.placeholder = NSLocalizedString("SERVER", comment: "")
portField.placeholder = NSLocalizedString("SERVER_PORT", comment: "")
portField.keyboardType = UIKeyboardType.numberPad
usernameField.placeholder = NSLocalizedString("USER_LABEL", comment: "")
passwordField.placeholder = NSLocalizedString("PASSWORD_LABEL", comment: "")
workgroupField.placeholder = NSLocalizedString("DSM_WORKGROUP", comment: "")
workgroupField.isHidden = true
buttonSave.setTitle(NSLocalizedString("BUTTON_SAVE", comment: ""), for: .normal)
buttonConnect.setTitle(NSLocalizedString("BUTTON_CONNECT", comment: ""), for: .normal)
nothingFoundLabel.text = NSLocalizedString("NO_SAVING_DATA", comment: "")
}
@objc func ubiquitousKeyValueStoreDidChange(notification: NSNotification) {
serverList?.setArray(NSUbiquitousKeyValueStore.default.array(forKey: kVLCStoredServerList)!)
tableView.reloadData()
}
@objc func segmentedControlChanged(_ control: UISegmentedControl) {
let selectedIndex = control.selectedSegmentIndex
if selectedIndex == 0 {
workgroupField.isHidden = false
workgroupField.text = "WORKGROUP"
} else {
workgroupField.isHidden = true
workgroupField.text = ""
}
}
// MARK: - UILongPressGestureRecognizer Action
@objc func handleLongPress(gestureReconizer: UILongPressGestureRecognizer) {
if gestureReconizer.state == UIGestureRecognizer.State.ended {
return
}
let point = gestureReconizer.location(in: self.tableView)
if let indexPath = self.tableView.indexPathForRow(at: point) {
let cell = self.tableView.cellForRow(at: indexPath)
let alertController = UIAlertController(title: cell?.textLabel?.text,
message: cell?.detailTextLabel?.text,
preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: NSLocalizedString("BUTTON_CANCEL", comment: ""), style: .cancel, handler: nil))
alertController.addAction(UIAlertAction(title: NSLocalizedString("BUTTON_DELETE", comment: ""), style: .destructive, handler: { action in
self.deleteItem(indexPath.row)
}))
self.present(alertController, animated: true)
}
}
// MARK: -
func protocolIdentifierForProtocol(_ segmentedControl: UISegmentedControl) -> String? {
var protocolIdentifier: String? = nil
switch segmentedControl.selectedSegmentIndex {
case 0:
protocolIdentifier = VLCNetworkServerProtocolIdentifierSMB
break
case 1:
protocolIdentifier = VLCNetworkServerProtocolIdentifierFTP
break
case 2:
protocolIdentifier = VLCNetworkServerProtocolIdentifierPlex
break
default:
break
}
return protocolIdentifier
}
func setSegControlProtocolIdentifier(_ protocolIdentifier: String) {
switch protocolIdentifier {
case VLCNetworkServerProtocolIdentifierSMB:
segmentedControl.selectedSegmentIndex = 0
break
case VLCNetworkServerProtocolIdentifierFTP:
segmentedControl.selectedSegmentIndex = 1
break
case VLCNetworkServerProtocolIdentifierPlex:
segmentedControl.selectedSegmentIndex = 2
break
default:
break
}
}
func serverLoginInformation(protocolSection: String) -> VLCNetworkServerLoginInformation {
var login = VLCNetworkServerLoginInformation.init()
login = VLCNetworkServerLoginInformation.newLoginInformation(forProtocol: protocolSection)
login.address = serverField.text!
if !(portField.text?.isEmpty)! {
login.port = NSNumber.init(value: Int(portField.text!)!)
}
login.username = usernameField.text
login.password = passwordField.text
if login.protocolIdentifier == VLCNetworkServerProtocolIdentifierSMB {
for fieldInfo: VLCNetworkServerLoginInformationField in login.additionalFields {
fieldInfo.textValue = workgroupField.text ?? "WORKGROUP"
}
}
return login
}
func showBrowserWithLogin(_ login: VLCNetworkServerLoginInformation) {
var serverBrowser: VLCNetworkServerBrowser? = nil
let identifier = login.protocolIdentifier as NSString
if identifier.isEqual(to: VLCNetworkServerProtocolIdentifierFTP) {
serverBrowser = VLCNetworkServerBrowserFTP.init(login: login)
} else if identifier.isEqual(to: VLCNetworkServerProtocolIdentifierPlex) {
serverBrowser = VLCNetworkServerBrowserPlex.init(login: login)
} else if identifier.isEqual(to: VLCNetworkServerProtocolIdentifierSMB) {
serverBrowser = VLCNetworkServerBrowserVLCMedia.smbNetworkServerBrowser(withLogin: login)
}
if serverBrowser != nil {
let targetViewController: VLCServerBrowsingTVViewController = VLCSearchableServerBrowsingTVViewController.init(serverBrowser: serverBrowser!)
self.present(targetViewController, animated: true, completion: nil)
}
}
func deleteItem(_ row: NSInteger) {
let serviceString = serverList[row]
do {
try XKKeychainGenericPasswordItem.removeItems(forService: serviceString as? String)
} catch let error as NSError {
print("Failed to delete login with error: \(error)")
return
}
serverList.remove(serviceString)
let ukvStore = NSUbiquitousKeyValueStore.default
ukvStore.set(serverList, forKey: kVLCStoredServerList)
ukvStore.synchronize()
tableView.reloadData()
}
// MARK: - UITableView Data Source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let serverListCount = serverList.count
if serverListCount > 0 {
nothingFoundView.isHidden = true
} else {
nothingFoundView.isHidden = false
}
return serverList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "LoginSavedTableViewCell")
if cell == nil {
cell = UITableViewCell.init(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "LoginSavedTableViewCell")
}
let serviceString = serverList[indexPath.row]
let service = URL.init(string: serviceString as! String)
cell?.textLabel?.text = String(format: "%@ [%@]", service?.host ?? "", service?.scheme?.uppercased() ?? "")
do {
let keychainItem = try XKKeychainGenericPasswordItem.init(forService: (serviceString as? String), account: nil)
cell?.detailTextLabel?.text = keychainItem.account
} catch {
cell?.detailTextLabel?.text = ""
}
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let login = VLCNetworkServerLoginInformation.init(keychainIdentifier: serverList?[indexPath.row] as! String)
do {
try login.loadFromKeychain()
} catch {
print("Failed to load login from key chain")
return
}
setSegControlProtocolIdentifier(login.protocolIdentifier)
segmentedControlChanged(segmentedControl)
usernameField.text = login.username
passwordField.text = login.password
portField.text = login.port.stringValue
serverField.text = login.address
if login.protocolIdentifier == VLCNetworkServerProtocolIdentifierSMB {
for fieldInfo: VLCNetworkServerLoginInformationField in login.additionalFields {
workgroupField.text = fieldInfo.textValue
}
}
showBrowserWithLogin(login)
}
// MARK: - IBAction
@IBAction func saveLogin(_ sender: Any) {
let protocolSection = protocolIdentifierForProtocol(segmentedControl)
if protocolSection != nil {
let login = serverLoginInformation(protocolSection: protocolSection!)
do {
try login.saveToKeychain()
} catch let error as NSError {
// TODO : add vclalertview ?
print("Failed to save login with error: \(error)")
}
let serviceIdentifier = login.keychainServiceIdentifier
serverList.add(serviceIdentifier)
let ukvStore = NSUbiquitousKeyValueStore.default
ukvStore.set(serverList, forKey: kVLCStoredServerList)
ukvStore.synchronize()
tableView.reloadData()
//showBrowserWithLogin(login)
}
}
@IBAction func ConnectToServer(_ sender: Any) {
let protocolSection = protocolIdentifierForProtocol(segmentedControl)
if protocolSection != nil {
let login = serverLoginInformation(protocolSection: protocolSection!)
showBrowserWithLogin(login)
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder.AppleTV.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="appleTV" orientation="landscape">
<adaptation id="light"/>
</device>
<dependencies>
<deployment identifier="tvOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="VLCNetworkLoginTVViewController" customModule="VLC" customModuleProvider="target">
<connections>
<outlet property="buttonConnect" destination="sqn-ne-gi8" id="TXw-Lb-rui"/>
<outlet property="buttonSave" destination="c1A-mX-LxM" id="D3q-7B-e3U"/>
<outlet property="nothingFoundLabel" destination="xzD-hl-t2b" id="SCq-6a-vav"/>
<outlet property="nothingFoundView" destination="DRv-sP-mwh" id="vw5-ei-Twm"/>
<outlet property="passwordField" destination="vid-P5-6NG" id="EGV-IP-pNY"/>
<outlet property="portField" destination="PWg-iD-EqV" id="Zjv-GN-Y7v"/>
<outlet property="segmentedControl" destination="qoc-Y9-1Zo" id="Xfo-Ge-BZY"/>
<outlet property="serverField" destination="TKy-NO-Xtu" id="MXT-c7-08p"/>
<outlet property="tableView" destination="D8I-qj-1Ff" id="MDh-OF-VnW"/>
<outlet property="usernameField" destination="fOo-BA-aNJ" id="3ib-9c-PQ1"/>
<outlet property="view" destination="iN0-l3-epB" id="d1e-6i-lwj"/>
<outlet property="workgroupField" destination="vEX-VM-fdk" id="Mrx-7y-qXB"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Bjz-vU-NEt">
<rect key="frame" x="110" y="144" width="625" height="785"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="wYk-iy-RMM">
<rect key="frame" x="0.0" y="0.0" width="625" height="785"/>
<subviews>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" translatesAutoresizingMaskIntoConstraints="NO" id="qoc-Y9-1Zo" userLabel="segCtrl">
<rect key="frame" x="0.0" y="0.0" width="625" height="86"/>
<color key="backgroundColor" white="0.0" alpha="0.10000000000000001" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="85" id="7M2-5G-bsJ"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="82" id="Lva-1H-o23"/>
<constraint firstAttribute="width" constant="625" id="bcJ-OH-2IZ"/>
</constraints>
<segments>
<segment title="SMB"/>
<segment title="FTP"/>
<segment title="PLEX"/>
</segments>
</segmentedControl>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Server" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="TKy-NO-Xtu" userLabel="adress">
<rect key="frame" x="0.0" y="100" width="625" height="85"/>
<constraints>
<constraint firstAttribute="width" constant="625" id="KIs-Z4-nZt"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="82" id="NlA-gP-QeO"/>
<constraint firstAttribute="height" constant="85" id="q5y-bg-7nH"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle3"/>
<textInputTraits key="textInputTraits" enablesReturnKeyAutomatically="YES" textContentType="url"/>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Port" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="PWg-iD-EqV" userLabel="port">
<rect key="frame" x="0.0" y="200" width="625" height="85"/>
<constraints>
<constraint firstAttribute="height" constant="85" id="N3Q-zZ-p7t"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="82" id="T26-XZ-DdY"/>
<constraint firstAttribute="width" constant="625" id="ecM-lo-QrN"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle3"/>
<textInputTraits key="textInputTraits" enablesReturnKeyAutomatically="YES"/>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Login" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="fOo-BA-aNJ" userLabel="username">
<rect key="frame" x="0.0" y="300" width="625" height="85"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="82" id="2kk-Ab-KwE"/>
<constraint firstAttribute="width" constant="625" id="Q3z-58-itj"/>
<constraint firstAttribute="height" constant="85" id="kZ2-Bb-HZo"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle3"/>
<textInputTraits key="textInputTraits" enablesReturnKeyAutomatically="YES" textContentType="username"/>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Password" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="vid-P5-6NG" userLabel="password">
<rect key="frame" x="0.0" y="400" width="625" height="85"/>
<constraints>
<constraint firstAttribute="height" constant="85" id="0NJ-fx-5V8"/>
<constraint firstAttribute="width" constant="625" id="D8T-jw-2gb"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="82" id="EwO-UX-qrf"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle3"/>
<textInputTraits key="textInputTraits" enablesReturnKeyAutomatically="YES" secureTextEntry="YES" textContentType="password"/>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Workgroup" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="vEX-VM-fdk" userLabel="workgroup">
<rect key="frame" x="0.0" y="500" width="625" height="85"/>
<constraints>
<constraint firstAttribute="width" constant="625" id="0OP-rK-Al9"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="82" id="b9V-fk-mYd"/>
<constraint firstAttribute="height" constant="85" id="rRQ-V0-lSS"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle3"/>
<textInputTraits key="textInputTraits" enablesReturnKeyAutomatically="YES" textContentType="username"/>
</textField>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="c1A-mX-LxM" userLabel="save">
<rect key="frame" x="0.0" y="600" width="625" height="85"/>
<constraints>
<constraint firstAttribute="width" constant="625" id="OMu-dv-bOB"/>
<constraint firstAttribute="height" constant="85" id="oXV-CB-6K8"/>
</constraints>
<inset key="contentEdgeInsets" minX="40" minY="20" maxX="40" maxY="20"/>
<state key="normal" title="Save"/>
<connections>
<action selector="saveLogin:" destination="-1" eventType="primaryActionTriggered" id="pOg-1Q-pNA"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sqn-ne-gi8" userLabel="connect">
<rect key="frame" x="0.0" y="700" width="625" height="85"/>
<constraints>
<constraint firstAttribute="width" constant="625" id="CPw-Op-Wil"/>
<constraint firstAttribute="height" constant="85" id="M6k-nk-JKQ"/>
</constraints>
<inset key="contentEdgeInsets" minX="40" minY="20" maxX="40" maxY="20"/>
<state key="normal" title="Connect"/>
<connections>
<action selector="ConnectToServer:" destination="-1" eventType="primaryActionTriggered" id="CXY-In-rya"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
</stackView>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DRv-sP-mwh" userLabel="Nothing Found View">
<rect key="frame" x="1008" y="60" width="802" height="960"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="cone" translatesAutoresizingMaskIntoConstraints="NO" id="9TZ-BM-yM1">
<rect key="frame" x="328" y="349" width="143" height="158"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="nuting found" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xzD-hl-t2b">
<rect key="frame" x="0.0" y="579" width="802" height="46"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<color key="textColor" red="0.33333334329999997" green="0.33333334329999997" blue="0.33333334329999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<viewLayoutGuide key="safeArea" id="ToZ-7P-SRa"/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="grouped" separatorStyle="default" rowHeight="-1" sectionHeaderHeight="7" sectionFooterHeight="7" translatesAutoresizingMaskIntoConstraints="NO" id="D8I-qj-1Ff">
<rect key="frame" x="1008" y="60" width="802" height="960"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
</tableView>
</subviews>
<viewLayoutGuide key="safeArea" id="Pmt-tb-8Ig"/>
</view>
</objects>
<resources>
<image name="cone" width="143" height="158"/>
</resources>
</document>
......@@ -33,6 +33,8 @@
#import "VLCRemoteBrowsingTVCell.h"
#import "GRKArrayDiff+UICollectionView.h"
#import "VLC-Swift.h"
@interface VLCServerListTVViewController ()
{
UILabel *_nothingFoundLabel;
......@@ -83,6 +85,7 @@
[self.view addConstraint:xConstraint];
NSArray *classes = @[
[VLCLocalNetworkServiceBrowserManualConnect class],
[VLCLocalNetworkServiceBrowserHTTP class],
[VLCLocalNetworkServiceBrowserUPnP class],
[VLCLocalNetworkServiceBrowserDSM class],
......@@ -168,7 +171,12 @@
NSError *error = nil;
if ([login loadLoginInformationFromKeychainWithError:&error])
{
[self showLoginAlertWithLogin:login];
if (login.protocolIdentifier)
[self showLoginAlertWithLogin:login];
else {
VLCNetworkLoginTVViewController *targetViewController = [VLCNetworkLoginTVViewController alloc];
[self presentViewController:targetViewController animated:YES completion:nil];
}
} else {
[self showKeychainLoadError:error forLogin:login];
}
......
......@@ -69,3 +69,6 @@
#define kVLCSettingWiFiSharingIPv6DefaultValue @(NO)
#define kVLCfortvOSMovieDBKey @""
#define kVLCStoredServerList @"kVLCStoredServerList"
......@@ -9,6 +9,8 @@
/* Begin PBXBuildFile section */
14903A768F4E959C0828288C /* libPods-VLC-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 52DDBB38DF22E6BBD19C38C8 /* libPods-VLC-tvOS.a */; };
2629C888223991A400F8D080 /* VLCMediaThumbnailerCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2629C887223991A400F8D080 /* VLCMediaThumbnailerCache.swift */; };
2663ACB222497D21000FBB95 /* VLCNetworkLoginTVViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2663ACB122497D21000FBB95 /* VLCNetworkLoginTVViewController.swift */; };
2663ACB422497D47000FBB95 /* VLCNetworkLoginTVViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2663ACB322497D47000FBB95 /* VLCNetworkLoginTVViewController.xib */; };
26F1BFD01A770408001DF30C /* libMediaVLC.xml in Resources */ = {isa = PBXBuildFile; fileRef = 26F1BFCF1A770408001DF30C /* libMediaVLC.xml */; };
29125E5617492219003F03E5 /* index.html in Resources */ = {isa = PBXBuildFile; fileRef = 29125E5417492219003F03E5 /* index.html */; };
2915544317490D4A00B86CAD /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2915544217490D4A00B86CAD /* Security.framework */; };
......@@ -412,6 +414,8 @@
/* Begin PBXFileReference section */
2629C886223991A300F8D080 /* VLC-tvOS-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VLC-tvOS-Bridging-Header.h"; sourceTree = "<group>"; };
2629C887223991A400F8D080 /* VLCMediaThumbnailerCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VLCMediaThumbnailerCache.swift; sourceTree = "<group>"; };
2663ACB122497D21000FBB95 /* VLCNetworkLoginTVViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VLCNetworkLoginTVViewController.swift; sourceTree = "<group>"; };
2663ACB322497D47000FBB95 /* VLCNetworkLoginTVViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VLCNetworkLoginTVViewController.xib; sourceTree = "<group>"; };
268BDA7D1B4FE1E200D622DD /* backArrow_black.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = backArrow_black.png; path = ImportedSources/OneDrive/src/LiveSDK/Library/Internal/Resources/backArrow_black.png; sourceTree = SOURCE_ROOT; };
26F1BFCF1A770408001DF30C /* libMediaVLC.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = libMediaVLC.xml; sourceTree = "<group>"; };
29125E5417492219003F03E5 /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = index.html; sourceTree = "<group>"; };
......@@ -1679,6 +1683,7 @@
DD4089E81BF63AD00022745E /* VLCPlaybackInfoTracksTVViewController.xib */,
DD4089EE1BF646540022745E /* VLCPlaybackInfoTVCollectionViewCell.xib */,
7DC0B56F1C0094370027BFAD /* VLCSettingsViewController.xib */,
2663ACB322497D47000FBB95 /* VLCNetworkLoginTVViewController.xib */,
);
name = xibs;
sourceTree = "<group>";
......@@ -1748,6 +1753,7 @@
7D7EF3D81BD56B5900CD4CEE /* VLCOpenNetworkStreamTVViewController.m */,
7DB174A51CD20D7B0085BCF0 /* VLCSearchableServerBrowsingTVViewController.h */,
7DB174A61CD20D7B0085BCF0 /* VLCSearchableServerBrowsingTVViewController.m */,
2663ACB122497D21000FBB95 /* VLCNetworkLoginTVViewController.swift */,
);
name = "Network UI";
sourceTree = "<group>";
......@@ -2470,6 +2476,7 @@
DD9D8F681C01FAB500B4060F /* VLCPlaybackInfoChaptersTVViewController.xib in Resources */,
6B4E33D21BF2A39400A35255 /* playerControl.js in Resources */,
7DC0B5711C0094370027BFAD /* VLCSettingsViewController.xib in Resources */,
2663ACB422497D47000FBB95 /* VLCNetworkLoginTVViewController.xib in Resources */,
7D405ED81BEA1F56006ED886 /* jquery.iframe-transport.js in Resources */,
DD4089EF1BF646540022745E /* VLCPlaybackInfoTVCollectionViewCell.xib in Resources */,
DD3EAC131BE26166003668DA /* VLCRemoteBrowsingTVCell.xib in Resources */,
......@@ -2766,6 +2773,7 @@
DD8095E01BE3EFC20065D8E1 /* VLCPlaybackInfoTVViewController.m in Sources */,
DD9D8F651C01F96700B4060F /* VLCPlaybackInfoChaptersTVViewController.m in Sources */,
7DEC8C1F1BD6A113006E1093 /* UIDevice+VLC.m in Sources */,
2663ACB222497D21000FBB95 /* VLCNetworkLoginTVViewController.swift in Sources */,
DDEAECFE1BDFFAEE00756C83 /* Reachability.m in Sources */,
7DF383C41BF2329500D71A5C /* VLCDropboxCollectionViewController.m in Sources */,
DD3EFF561BDEBCE500B68579 /* VLCLocalNetworkServiceBrowserDSM.m in Sources */,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment