mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-27 19:33:02 +00:00
changes
This commit is contained in:
parent
9d5d5fa4e2
commit
e3d7ddb04a
3 changed files with 217 additions and 227 deletions
|
|
@ -1,34 +1,29 @@
|
|||
package com.nuvio.app
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Extension
|
||||
import androidx.compose.material.icons.rounded.Home
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.NavigationBar
|
||||
import androidx.compose.material3.NavigationBarItem
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.toRoute
|
||||
import coil3.ImageLoader
|
||||
|
|
@ -95,39 +90,36 @@ fun App() {
|
|||
}
|
||||
NuvioTheme {
|
||||
val navController = rememberNavController()
|
||||
val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route
|
||||
var selectedTab by rememberSaveable { mutableStateOf(AppScreenTab.Home) }
|
||||
|
||||
// iOS-only: StreamsScreen is presented as a native modal sheet instead of
|
||||
// a NavHost destination. On Android this stays null and navController is used.
|
||||
var pendingStream by remember { mutableStateOf<StreamRoute?>(null) }
|
||||
|
||||
val onPlay: (String, String, String, String?, String?, String?, Int?, Int?, String?, String?) -> Unit =
|
||||
{ type, videoId, title, logo, poster, background, seasonNumber, episodeNumber, episodeTitle, episodeThumbnail ->
|
||||
val route = StreamRoute(
|
||||
type = type,
|
||||
videoId = videoId,
|
||||
title = title,
|
||||
logo = logo,
|
||||
poster = poster,
|
||||
background = background,
|
||||
seasonNumber = seasonNumber,
|
||||
episodeNumber = episodeNumber,
|
||||
episodeTitle = episodeTitle,
|
||||
episodeThumbnail = episodeThumbnail,
|
||||
navController.navigate(
|
||||
StreamRoute(
|
||||
type = type,
|
||||
videoId = videoId,
|
||||
title = title,
|
||||
logo = logo,
|
||||
poster = poster,
|
||||
background = background,
|
||||
seasonNumber = seasonNumber,
|
||||
episodeNumber = episodeNumber,
|
||||
episodeTitle = episodeTitle,
|
||||
episodeThumbnail = episodeThumbnail,
|
||||
)
|
||||
)
|
||||
if (isIos) {
|
||||
pendingStream = route
|
||||
} else {
|
||||
navController.navigate(route)
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
containerColor = MaterialTheme.colorScheme.background,
|
||||
contentWindowInsets = WindowInsets(0),
|
||||
bottomBar = {
|
||||
if (currentRoute == TabsRoute::class.qualifiedName) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colorScheme.background),
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
containerColor = MaterialTheme.colorScheme.background,
|
||||
contentWindowInsets = WindowInsets(0),
|
||||
bottomBar = {
|
||||
NavigationBar(
|
||||
containerColor = MaterialTheme.colorScheme.surface,
|
||||
windowInsets = WindowInsets(0),
|
||||
|
|
@ -145,21 +137,24 @@ fun App() {
|
|||
label = { Text("Addons") },
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
) { innerPadding ->
|
||||
},
|
||||
) { innerPadding ->
|
||||
AppScreen(
|
||||
tab = selectedTab,
|
||||
modifier = Modifier.padding(innerPadding),
|
||||
onPosterClick = { meta ->
|
||||
navController.navigate(DetailRoute(type = meta.type, id = meta.id))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = TabsRoute,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
composable<TabsRoute> {
|
||||
AppScreen(
|
||||
tab = selectedTab,
|
||||
modifier = Modifier.padding(innerPadding),
|
||||
onPosterClick = { meta ->
|
||||
navController.navigate(DetailRoute(type = meta.type, id = meta.id))
|
||||
},
|
||||
)
|
||||
Unit
|
||||
}
|
||||
composable<DetailRoute> { backStackEntry ->
|
||||
val route = backStackEntry.toRoute<DetailRoute>()
|
||||
|
|
@ -171,10 +166,9 @@ fun App() {
|
|||
navController.popBackStack()
|
||||
},
|
||||
onPlay = onPlay,
|
||||
modifier = Modifier.padding(innerPadding),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
}
|
||||
// Android only: iOS uses the modal sheet below instead
|
||||
composable<StreamRoute> { backStackEntry ->
|
||||
val route = backStackEntry.toRoute<StreamRoute>()
|
||||
StreamsScreen(
|
||||
|
|
@ -192,42 +186,10 @@ fun App() {
|
|||
StreamsRepository.clear()
|
||||
navController.popBackStack()
|
||||
},
|
||||
modifier = Modifier.padding(innerPadding),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iOS native modal sheet presentation for StreamsScreen
|
||||
pendingStream?.let { route ->
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = {
|
||||
StreamsRepository.clear()
|
||||
pendingStream = null
|
||||
},
|
||||
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
|
||||
containerColor = Color.Transparent,
|
||||
contentColor = MaterialTheme.colorScheme.onBackground,
|
||||
dragHandle = null,
|
||||
contentWindowInsets = { WindowInsets.safeDrawing.only(WindowInsetsSides.Top) },
|
||||
) {
|
||||
StreamsScreen(
|
||||
type = route.type,
|
||||
videoId = route.videoId,
|
||||
title = route.title,
|
||||
logo = route.logo,
|
||||
poster = route.poster,
|
||||
background = route.background,
|
||||
seasonNumber = route.seasonNumber,
|
||||
episodeNumber = route.episodeNumber,
|
||||
episodeTitle = route.episodeTitle,
|
||||
episodeThumbnail = route.episodeThumbnail,
|
||||
onBack = {
|
||||
StreamsRepository.clear()
|
||||
pendingStream = null
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@
|
|||
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||
69649F6DF5D3AF53A24CA9C3 /* Configuration */ = {
|
||||
isa = PBXFileSystemSynchronizedRootGroup;
|
||||
path = Configuration;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A2F97F59D21EB4D4B662C8D1 /* iosApp */ = {
|
||||
isa = PBXFileSystemSynchronizedRootGroup;
|
||||
exceptions = (
|
||||
|
|
@ -29,11 +34,6 @@
|
|||
path = iosApp;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
69649F6DF5D3AF53A24CA9C3 /* Configuration */ = {
|
||||
isa = PBXFileSystemSynchronizedRootGroup;
|
||||
path = Configuration;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -167,6 +167,120 @@
|
|||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
08C6158BC74ED5D18954BFD9 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReferenceAnchor = 69649F6DF5D3AF53A24CA9C3 /* Configuration */;
|
||||
baseConfigurationReferenceRelativePath = Config.xcconfig;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 18.2;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
3BEA88C53B91734AEB44313E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = arm64;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = 8QBDZ766S3;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = iosApp/Info.plist;
|
||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
4322E267F98B668D798FAEEE /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = arm64;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = 8QBDZ766S3;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = iosApp/Info.plist;
|
||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
7E47803C8E15431AEC9C9A71 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReferenceAnchor = 69649F6DF5D3AF53A24CA9C3 /* Configuration */;
|
||||
|
|
@ -232,120 +346,6 @@
|
|||
};
|
||||
name = Debug;
|
||||
};
|
||||
08C6158BC74ED5D18954BFD9 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReferenceAnchor = 69649F6DF5D3AF53A24CA9C3 /* Configuration */;
|
||||
baseConfigurationReferenceRelativePath = Config.xcconfig;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 18.2;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
4322E267F98B668D798FAEEE /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = arm64;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = "${TEAM_ID}";
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = iosApp/Info.plist;
|
||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3BEA88C53B91734AEB44313E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = arm64;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = "${TEAM_ID}";
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = iosApp/Info.plist;
|
||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
|
|
@ -370,4 +370,4 @@
|
|||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = E819B502921EC7C68AC4965A /* Project object */;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@ ANDROID_ACTIVITY=".MainActivity"
|
|||
IOS_PROJECT="$ROOT_DIR/iosApp/iosApp.xcodeproj"
|
||||
IOS_SCHEME="iosApp"
|
||||
IOS_DERIVED_DATA="$ROOT_DIR/build/ios-derived"
|
||||
IOS_APP_PATH="$IOS_DERIVED_DATA/Build/Products/Debug-iphonesimulator/Nuvio.app"
|
||||
IOS_APP_NAME="Nuvio.app"
|
||||
IOS_BUNDLE_ID="com.nuvio.app.Nuvio"
|
||||
IOS_PREFERRED_DEVICE_MODEL="iPhone 14 Pro"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
|
|
@ -20,7 +21,7 @@ Usage:
|
|||
./scripts/run-mobile.sh ios
|
||||
|
||||
Builds the debug app for the selected platform, installs it on the first running
|
||||
Android emulator or booted iOS simulator, and launches the app.
|
||||
Android emulator or the configured iOS device target, and launches the app.
|
||||
EOF
|
||||
}
|
||||
|
||||
|
|
@ -39,6 +40,30 @@ first_booted_ios_simulator() {
|
|||
xcrun simctl list devices booted | awk -F '[()]' '/Booted/ { print $2; exit }'
|
||||
}
|
||||
|
||||
preferred_ios_device() {
|
||||
xcrun xcdevice list --timeout 5 2>/dev/null | python3 -c '
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
devices = json.load(sys.stdin)
|
||||
except Exception:
|
||||
sys.exit(0)
|
||||
|
||||
physical = [
|
||||
device for device in devices
|
||||
if device.get("platform") == "com.apple.platform.iphoneos"
|
||||
and not device.get("simulator", False)
|
||||
and device.get("available") is True
|
||||
and device.get("modelName") == os.environ["IOS_PREFERRED_DEVICE_MODEL"]
|
||||
]
|
||||
|
||||
if physical:
|
||||
print(physical[0].get("identifier", ""))
|
||||
'
|
||||
}
|
||||
|
||||
run_android() {
|
||||
require_command adb
|
||||
|
||||
|
|
@ -73,35 +98,38 @@ run_ios() {
|
|||
require_command xcodebuild
|
||||
require_command xcrun
|
||||
|
||||
local simulator_udid
|
||||
simulator_udid="$(first_booted_ios_simulator)"
|
||||
local physical_device_id
|
||||
physical_device_id="$(IOS_PREFERRED_DEVICE_MODEL="$IOS_PREFERRED_DEVICE_MODEL" preferred_ios_device)"
|
||||
|
||||
if [[ -z "$simulator_udid" ]]; then
|
||||
echo "No booted iOS simulator found." >&2
|
||||
echo "Start a simulator first, then rerun: ./scripts/run-mobile.sh ios" >&2
|
||||
exit 1
|
||||
if [[ -n "$physical_device_id" ]]; then
|
||||
local device_app_path
|
||||
device_app_path="$IOS_DERIVED_DATA/Build/Products/Debug-iphoneos/$IOS_APP_NAME"
|
||||
|
||||
echo "Building iOS debug app for physical device $physical_device_id..."
|
||||
xcodebuild \
|
||||
-project "$IOS_PROJECT" \
|
||||
-scheme "$IOS_SCHEME" \
|
||||
-configuration Debug \
|
||||
-destination "id=$physical_device_id" \
|
||||
-derivedDataPath "$IOS_DERIVED_DATA" \
|
||||
build
|
||||
|
||||
if [[ ! -d "$device_app_path" ]]; then
|
||||
echo "Expected iOS app not found at: $device_app_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing on physical device $physical_device_id..."
|
||||
xcrun devicectl device install app --device "$physical_device_id" "$device_app_path"
|
||||
|
||||
echo "Launching app..."
|
||||
xcrun devicectl device process launch --device "$physical_device_id" "$IOS_BUNDLE_ID"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Building iOS debug app for simulator $simulator_udid..."
|
||||
xcodebuild \
|
||||
-project "$IOS_PROJECT" \
|
||||
-scheme "$IOS_SCHEME" \
|
||||
-configuration Debug \
|
||||
-destination "id=$simulator_udid" \
|
||||
-derivedDataPath "$IOS_DERIVED_DATA" \
|
||||
CODE_SIGNING_ALLOWED=NO \
|
||||
build
|
||||
|
||||
if [[ ! -d "$IOS_APP_PATH" ]]; then
|
||||
echo "Expected iOS app not found at: $IOS_APP_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing on simulator $simulator_udid..."
|
||||
xcrun simctl install "$simulator_udid" "$IOS_APP_PATH"
|
||||
|
||||
echo "Launching app..."
|
||||
xcrun simctl launch "$simulator_udid" "$IOS_BUNDLE_ID"
|
||||
echo "Preferred iOS device not available: $IOS_PREFERRED_DEVICE_MODEL" >&2
|
||||
echo "Connect and unlock that device, then rerun: ./scripts/run-mobile.sh ios" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
main() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue