Replace R.swift with Swiftgen
This commit is contained in:
parent
1e0ae4745c
commit
6307ae4e26
|
@ -96,4 +96,4 @@ iOSInjectionProject/
|
||||||
.Trashes
|
.Trashes
|
||||||
ehthumbs.db
|
ehthumbs.db
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
Shared/Generated/R.generated.swift
|
Shared/Generated/Strings.swift
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct MediaPlayButtonRowView: View {
|
||||||
NavigationLink(destination: VideoPlayerView(item: viewModel.item).ignoresSafeArea()) {
|
NavigationLink(destination: VideoPlayerView(item: viewModel.item).ignoresSafeArea()) {
|
||||||
MediaViewActionButton(icon: "play.fill", scrollView: $wrappedScrollView)
|
MediaViewActionButton(icon: "play.fill", scrollView: $wrappedScrollView)
|
||||||
}
|
}
|
||||||
Text(viewModel.item.getItemProgressString() != "" ? "\(viewModel.item.getItemProgressString()) left" : R.string.localizable.play())
|
Text(viewModel.item.getItemProgressString() != "" ? "\(viewModel.item.getItemProgressString()) left" : L10n.play)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
}
|
}
|
||||||
VStack {
|
VStack {
|
||||||
|
|
|
@ -68,7 +68,7 @@ struct PortraitItemElement: View {
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
} else {
|
} else {
|
||||||
Text(R.string.localizable.seasonAndEpisode(String(item.parentIndexNumber ?? 0), String(item.indexNumber ?? 0)))
|
Text(L10n.seasonAndEpisode(String(item.parentIndexNumber ?? 0), String(item.indexNumber ?? 0)))
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct BasicAppSettingsView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
Section {
|
Section {
|
||||||
Picker(R.string.localizable.appearance(), selection: $appAppearance) {
|
Picker(L10n.appearance, selection: $appAppearance) {
|
||||||
ForEach(self.viewModel.appearances, id: \.self) { appearance in
|
ForEach(self.viewModel.appearances, id: \.self) { appearance in
|
||||||
Text(appearance.localizedName).tag(appearance.rawValue)
|
Text(appearance.localizedName).tag(appearance.rawValue)
|
||||||
}
|
}
|
||||||
|
@ -30,21 +30,21 @@ struct BasicAppSettingsView: View {
|
||||||
UIApplication.shared.windows.first?.overrideUserInterfaceStyle = appAppearance.style
|
UIApplication.shared.windows.first?.overrideUserInterfaceStyle = appAppearance.style
|
||||||
})
|
})
|
||||||
} header: {
|
} header: {
|
||||||
R.string.localizable.accessibility.text
|
L10n.accessibility.text
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
resetTapped = true
|
resetTapped = true
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.reset.text
|
L10n.reset.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.alert(R.string.localizable.reset(), isPresented: $resetTapped, actions: {
|
.alert(L10n.reset, isPresented: $resetTapped, actions: {
|
||||||
Button(role: .destructive) {
|
Button(role: .destructive) {
|
||||||
viewModel.reset()
|
viewModel.reset()
|
||||||
basicAppSettingsRouter.dismissCoordinator()
|
basicAppSettingsRouter.dismissCoordinator()
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.reset.text
|
L10n.reset.text
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.navigationTitle("Settings")
|
.navigationTitle("Settings")
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct ConnectToServerView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
List {
|
||||||
Section {
|
Section {
|
||||||
TextField(R.string.localizable.serverURL(), text: $uri)
|
TextField(L10n.serverURL, text: $uri)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.keyboardType(.URL)
|
.keyboardType(.URL)
|
||||||
|
@ -25,7 +25,7 @@ struct ConnectToServerView: View {
|
||||||
viewModel.connectToServer(uri: uri)
|
viewModel.connectToServer(uri: uri)
|
||||||
} label: {
|
} label: {
|
||||||
HStack {
|
HStack {
|
||||||
R.string.localizable.connect.text
|
L10n.connect.text
|
||||||
Spacer()
|
Spacer()
|
||||||
if viewModel.isLoading {
|
if viewModel.isLoading {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
|
@ -37,7 +37,7 @@ struct ConnectToServerView: View {
|
||||||
Text("Connect to a Jellyfin server")
|
Text("Connect to a Jellyfin server")
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: R.string.localizable.localServers.text) {
|
Section(header: L10n.localServers.text) {
|
||||||
if viewModel.searching {
|
if viewModel.searching {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,6 @@ struct ConnectToServerView: View {
|
||||||
message: Text(viewModel.errorMessage?.displayMessage ?? "Unknown Error"),
|
message: Text(viewModel.errorMessage?.displayMessage ?? "Unknown Error"),
|
||||||
dismissButton: .cancel())
|
dismissButton: .cancel())
|
||||||
}
|
}
|
||||||
.navigationTitle(R.string.localizable.connect())
|
.navigationTitle(L10n.connect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct ContinueWatchingView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
if items.count > 0 {
|
if items.count > 0 {
|
||||||
R.string.localizable.continueWatching.text
|
L10n.continueWatching.text
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.padding(.leading, 90)
|
.padding(.leading, 90)
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct HomeView: View {
|
||||||
self.homeRouter.route(to: \.modalLibrary, (.init(parentID: libraryID, filters: viewModel.recentFilterSet), title: library?.name ?? ""))
|
self.homeRouter.route(to: \.modalLibrary, (.init(parentID: libraryID, filters: viewModel.recentFilterSet), title: library?.name ?? ""))
|
||||||
} label: {
|
} label: {
|
||||||
HStack {
|
HStack {
|
||||||
Text(R.string.localizable.latestWithString(library?.name ?? ""))
|
Text(L10n.latestWithString(library?.name ?? ""))
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
Image(systemName: "chevron.forward.circle.fill")
|
Image(systemName: "chevron.forward.circle.fill")
|
||||||
|
|
|
@ -76,7 +76,7 @@ struct EpisodeItemView: View {
|
||||||
HStack(alignment: .top) {
|
HStack(alignment: .top) {
|
||||||
VStack(alignment: .trailing) {
|
VStack(alignment: .trailing) {
|
||||||
if studio != nil {
|
if studio != nil {
|
||||||
R.string.localizable.studio.text
|
L10n.studio.text
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
@ -88,7 +88,7 @@ struct EpisodeItemView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if director != nil {
|
if director != nil {
|
||||||
R.string.localizable.director.text
|
L10n.director.text
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
@ -100,7 +100,7 @@ struct EpisodeItemView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !actors.isEmpty {
|
if !actors.isEmpty {
|
||||||
R.string.localizable.cast.text
|
L10n.cast.text
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
@ -133,7 +133,7 @@ struct EpisodeItemView: View {
|
||||||
NavigationLink(destination: VideoPlayerView(item: viewModel.item).ignoresSafeArea()) {
|
NavigationLink(destination: VideoPlayerView(item: viewModel.item).ignoresSafeArea()) {
|
||||||
MediaViewActionButton(icon: "play.fill")
|
MediaViewActionButton(icon: "play.fill")
|
||||||
}
|
}
|
||||||
Text(viewModel.item.getItemProgressString() != "" ? "\(viewModel.item.getItemProgressString()) left" : R.string.localizable.play())
|
Text(viewModel.item.getItemProgressString() != "" ? "\(viewModel.item.getItemProgressString()) left" : L10n.play)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
}
|
}
|
||||||
VStack {
|
VStack {
|
||||||
|
@ -152,7 +152,7 @@ struct EpisodeItemView: View {
|
||||||
}.padding(.top, 50)
|
}.padding(.top, 50)
|
||||||
|
|
||||||
if !viewModel.similarItems.isEmpty {
|
if !viewModel.similarItems.isEmpty {
|
||||||
R.string.localizable.moreLikeThis.text
|
L10n.moreLikeThis.text
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
ScrollView(.horizontal) {
|
ScrollView(.horizontal) {
|
||||||
|
|
|
@ -40,7 +40,7 @@ struct ItemView: View {
|
||||||
} else if item.type == "Episode" {
|
} else if item.type == "Episode" {
|
||||||
EpisodeItemView(viewModel: .init(item: item))
|
EpisodeItemView(viewModel: .init(item: item))
|
||||||
} else {
|
} else {
|
||||||
Text(R.string.localizable.notImplementedYetWithType(item.type ?? ""))
|
Text(L10n.notImplementedYetWithType(item.type ?? ""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ struct MovieItemView: View {
|
||||||
HStack {
|
HStack {
|
||||||
VStack(alignment: .trailing) {
|
VStack(alignment: .trailing) {
|
||||||
if studio != nil {
|
if studio != nil {
|
||||||
R.string.localizable.studio.text
|
L10n.studio.text
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
@ -89,7 +89,7 @@ struct MovieItemView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if director != nil {
|
if director != nil {
|
||||||
R.string.localizable.director.text
|
L10n.director.text
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
@ -101,7 +101,7 @@ struct MovieItemView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !actors.isEmpty {
|
if !actors.isEmpty {
|
||||||
R.string.localizable.cast.text
|
L10n.cast.text
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
@ -133,7 +133,7 @@ struct MovieItemView: View {
|
||||||
}.padding(.top, 50)
|
}.padding(.top, 50)
|
||||||
|
|
||||||
if !viewModel.similarItems.isEmpty {
|
if !viewModel.similarItems.isEmpty {
|
||||||
R.string.localizable.moreLikeThis.text
|
L10n.moreLikeThis.text
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
ScrollView(.horizontal) {
|
ScrollView(.horizontal) {
|
||||||
|
|
|
@ -95,7 +95,7 @@ struct SeasonItemView: View {
|
||||||
}.padding(.top, 50)
|
}.padding(.top, 50)
|
||||||
|
|
||||||
if !viewModel.episodes.isEmpty {
|
if !viewModel.episodes.isEmpty {
|
||||||
R.string.localizable.episodes.text
|
L10n.episodes.text
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
ScrollView(.horizontal) {
|
ScrollView(.horizontal) {
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct SeriesItemView: View {
|
||||||
HStack {
|
HStack {
|
||||||
VStack(alignment: .trailing) {
|
VStack(alignment: .trailing) {
|
||||||
if studio != nil {
|
if studio != nil {
|
||||||
R.string.localizable.studio.text
|
L10n.studio.text
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
@ -91,7 +91,7 @@ struct SeriesItemView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if director != nil {
|
if director != nil {
|
||||||
R.string.localizable.director.text
|
L10n.director.text
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
@ -103,7 +103,7 @@ struct SeriesItemView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !actors.isEmpty {
|
if !actors.isEmpty {
|
||||||
R.string.localizable.cast.text
|
L10n.cast.text
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
@ -135,7 +135,7 @@ struct SeriesItemView: View {
|
||||||
}
|
}
|
||||||
}.padding(.top, 50)
|
}.padding(.top, 50)
|
||||||
if !viewModel.seasons.isEmpty {
|
if !viewModel.seasons.isEmpty {
|
||||||
R.string.localizable.seasons.text
|
L10n.seasons.text
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
ScrollView(.horizontal) {
|
ScrollView(.horizontal) {
|
||||||
|
@ -153,7 +153,7 @@ struct SeriesItemView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !viewModel.similarItems.isEmpty {
|
if !viewModel.similarItems.isEmpty {
|
||||||
R.string.localizable.moreLikeThis.text
|
L10n.moreLikeThis.text
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
ScrollView(.horizontal) {
|
ScrollView(.horizontal) {
|
||||||
|
|
|
@ -31,32 +31,32 @@ struct LibraryFilterView: View {
|
||||||
} else {
|
} else {
|
||||||
Form {
|
Form {
|
||||||
if viewModel.enabledFilterType.contains(.genre) {
|
if viewModel.enabledFilterType.contains(.genre) {
|
||||||
MultiSelector(label: R.string.localizable.genres(),
|
MultiSelector(label: L10n.genres,
|
||||||
options: viewModel.possibleGenres,
|
options: viewModel.possibleGenres,
|
||||||
optionToString: { $0.name ?? "" },
|
optionToString: { $0.name ?? "" },
|
||||||
selected: $viewModel.modifiedFilters.withGenres)
|
selected: $viewModel.modifiedFilters.withGenres)
|
||||||
}
|
}
|
||||||
if viewModel.enabledFilterType.contains(.filter) {
|
if viewModel.enabledFilterType.contains(.filter) {
|
||||||
MultiSelector(label: R.string.localizable.filters(),
|
MultiSelector(label: L10n.filters,
|
||||||
options: viewModel.possibleItemFilters,
|
options: viewModel.possibleItemFilters,
|
||||||
optionToString: { $0.localized },
|
optionToString: { $0.localized },
|
||||||
selected: $viewModel.modifiedFilters.filters)
|
selected: $viewModel.modifiedFilters.filters)
|
||||||
}
|
}
|
||||||
if viewModel.enabledFilterType.contains(.tag) {
|
if viewModel.enabledFilterType.contains(.tag) {
|
||||||
MultiSelector(label: R.string.localizable.tags(),
|
MultiSelector(label: L10n.tags,
|
||||||
options: viewModel.possibleTags,
|
options: viewModel.possibleTags,
|
||||||
optionToString: { $0 },
|
optionToString: { $0 },
|
||||||
selected: $viewModel.modifiedFilters.tags)
|
selected: $viewModel.modifiedFilters.tags)
|
||||||
}
|
}
|
||||||
if viewModel.enabledFilterType.contains(.sortBy) {
|
if viewModel.enabledFilterType.contains(.sortBy) {
|
||||||
Picker(selection: $viewModel.selectedSortBy, label: R.string.localizable.sortBy.text) {
|
Picker(selection: $viewModel.selectedSortBy, label: L10n.sortBy.text) {
|
||||||
ForEach(viewModel.possibleSortBys, id: \.self) { so in
|
ForEach(viewModel.possibleSortBys, id: \.self) { so in
|
||||||
Text(so.localized).tag(so)
|
Text(so.localized).tag(so)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if viewModel.enabledFilterType.contains(.sortOrder) {
|
if viewModel.enabledFilterType.contains(.sortOrder) {
|
||||||
Picker(selection: $viewModel.selectedSortOrder, label: R.string.localizable.displayOrder.text) {
|
Picker(selection: $viewModel.selectedSortOrder, label: L10n.displayOrder.text) {
|
||||||
ForEach(viewModel.possibleSortOrders, id: \.self) { so in
|
ForEach(viewModel.possibleSortOrders, id: \.self) { so in
|
||||||
Text(so.rawValue).tag(so)
|
Text(so.rawValue).tag(so)
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ struct LibraryFilterView: View {
|
||||||
self.filters = viewModel.modifiedFilters
|
self.filters = viewModel.modifiedFilters
|
||||||
filterRouter.dismissCoordinator()
|
filterRouter.dismissCoordinator()
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.reset.text
|
L10n.reset.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ struct LibraryFilterView: View {
|
||||||
self.filters = viewModel.modifiedFilters
|
self.filters = viewModel.modifiedFilters
|
||||||
filterRouter.dismissCoordinator()
|
filterRouter.dismissCoordinator()
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.apply.text
|
L10n.apply.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct LibrarySearchView: View {
|
||||||
var suggestionsListView: some View {
|
var suggestionsListView: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
LazyVStack(spacing: 8) {
|
LazyVStack(spacing: 8) {
|
||||||
R.string.localizable.suggestions.text
|
L10n.suggestions.text
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
|
|
@ -88,7 +88,7 @@ struct LibraryView: View {
|
||||||
.ignoresSafeArea(.all)
|
.ignoresSafeArea(.all)
|
||||||
} else {
|
} else {
|
||||||
VStack {
|
VStack {
|
||||||
R.string.localizable.noResults.text
|
L10n.noResults.text
|
||||||
Button { } label: {
|
Button { } label: {
|
||||||
Text("Reload")
|
Text("Reload")
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ struct MovieLibrariesView: View {
|
||||||
.ignoresSafeArea(.all)
|
.ignoresSafeArea(.all)
|
||||||
} else {
|
} else {
|
||||||
VStack {
|
VStack {
|
||||||
R.string.localizable.noResults.text
|
L10n.noResults.text
|
||||||
Button {
|
Button {
|
||||||
print("movieLibraries reload")
|
print("movieLibraries reload")
|
||||||
} label: {
|
} label: {
|
||||||
|
|
|
@ -19,7 +19,7 @@ struct NextUpView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
if items.count > 0 {
|
if items.count > 0 {
|
||||||
R.string.localizable.nextUp.text
|
L10n.nextUp.text
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.padding(.leading, 90)
|
.padding(.leading, 90)
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct ServerListView: View {
|
||||||
Button {
|
Button {
|
||||||
serverListRouter.route(to: \.connectToServer)
|
serverListRouter.route(to: \.connectToServer)
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.connect.text
|
L10n.connect.text
|
||||||
.bold()
|
.bold()
|
||||||
.font(.callout)
|
.font(.callout)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct SettingsView: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
Section(header: R.string.localizable.playbackSettings()) {
|
Section(header: L10n.playbackSettings) {
|
||||||
Picker("Default local quality", selection: $inNetworkStreamBitrate) {
|
Picker("Default local quality", selection: $inNetworkStreamBitrate) {
|
||||||
ForEach(self.viewModel.bitrates, id: \.self) { bitrate in
|
ForEach(self.viewModel.bitrates, id: \.self) { bitrate in
|
||||||
Text(bitrate.name).tag(bitrate.value)
|
Text(bitrate.name).tag(bitrate.value)
|
||||||
|
@ -36,7 +36,7 @@ struct SettingsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: R.string.localizable.accessibility.text) {
|
Section(header: L10n.accessibility.text) {
|
||||||
Toggle("Automatically show subtitles", isOn: $isAutoSelectSubtitles)
|
Toggle("Automatically show subtitles", isOn: $isAutoSelectSubtitles)
|
||||||
SearchablePicker(label: "Preferred subtitle language",
|
SearchablePicker(label: "Preferred subtitle language",
|
||||||
options: viewModel.langs,
|
options: viewModel.langs,
|
||||||
|
@ -58,12 +58,12 @@ struct SettingsView: View {
|
||||||
|
|
||||||
Section(header: Text(SessionManager.main.currentLogin.server.name)) {
|
Section(header: Text(SessionManager.main.currentLogin.server.name)) {
|
||||||
HStack {
|
HStack {
|
||||||
Text(R.string.localizable.signedInAsWithString(SessionManager.main.currentLogin.user.username))).foregroundColor(.primary)
|
Text(L10n.signedInAsWithString(SessionManager.main.currentLogin.user.username))).foregroundColor(.primary)
|
||||||
Spacer()
|
Spacer()
|
||||||
Button {
|
Button {
|
||||||
SwiftfinNotificationCenter.main.post(name: SwiftfinNotificationCenter.Keys.didSignOut, object: nil)
|
SwiftfinNotificationCenter.main.post(name: SwiftfinNotificationCenter.Keys.didSignOut, object: nil)
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.switchUser.text.font(.callout)
|
L10n.switchUser.text.font(.callout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
|
|
|
@ -77,7 +77,7 @@ struct TVLibrariesView: View {
|
||||||
.ignoresSafeArea(.all)
|
.ignoresSafeArea(.all)
|
||||||
} else {
|
} else {
|
||||||
VStack {
|
VStack {
|
||||||
R.string.localizable.noResults.text
|
L10n.noResults.text
|
||||||
Button {
|
Button {
|
||||||
print("tvLibraries reload")
|
print("tvLibraries reload")
|
||||||
} label: {
|
} label: {
|
||||||
|
|
|
@ -20,11 +20,11 @@ struct UserSignInView: View {
|
||||||
Form {
|
Form {
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
TextField(R.string.localizable.username(), text: $username)
|
TextField(L10n.username, text: $username)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
|
|
||||||
SecureField(R.string.localizable.password(), text: $password)
|
SecureField(L10n.password, text: $password)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ struct UserSignInView: View {
|
||||||
viewModel.login(username: username, password: password)
|
viewModel.login(username: username, password: password)
|
||||||
} label: {
|
} label: {
|
||||||
HStack {
|
HStack {
|
||||||
R.string.localizable.connect.text
|
L10n.connect.text
|
||||||
Spacer()
|
Spacer()
|
||||||
if viewModel.isLoading {
|
if viewModel.isLoading {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
|
|
|
@ -157,7 +157,6 @@
|
||||||
62133890265F83A900A81A2A /* LibraryListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6213388F265F83A900A81A2A /* LibraryListView.swift */; };
|
62133890265F83A900A81A2A /* LibraryListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6213388F265F83A900A81A2A /* LibraryListView.swift */; };
|
||||||
621338932660107500A81A2A /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621338922660107500A81A2A /* StringExtensions.swift */; };
|
621338932660107500A81A2A /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621338922660107500A81A2A /* StringExtensions.swift */; };
|
||||||
621338B32660A07800A81A2A /* LazyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621338B22660A07800A81A2A /* LazyView.swift */; };
|
621338B32660A07800A81A2A /* LazyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621338B22660A07800A81A2A /* LazyView.swift */; };
|
||||||
62167B882738411700167ECE /* R.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6286F0A0271C0AA500C40ED5 /* R.generated.swift */; };
|
|
||||||
6220D0AD26D5EABB00B8E046 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0AC26D5EABB00B8E046 /* ViewExtensions.swift */; };
|
6220D0AD26D5EABB00B8E046 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0AC26D5EABB00B8E046 /* ViewExtensions.swift */; };
|
||||||
6220D0AE26D5EABB00B8E046 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0AC26D5EABB00B8E046 /* ViewExtensions.swift */; };
|
6220D0AE26D5EABB00B8E046 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0AC26D5EABB00B8E046 /* ViewExtensions.swift */; };
|
||||||
6220D0AF26D5EABE00B8E046 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0AC26D5EABB00B8E046 /* ViewExtensions.swift */; };
|
6220D0AF26D5EABE00B8E046 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0AC26D5EABB00B8E046 /* ViewExtensions.swift */; };
|
||||||
|
@ -177,6 +176,9 @@
|
||||||
625CB5772678C34300530A6E /* ConnectToServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 625CB5762678C34300530A6E /* ConnectToServerViewModel.swift */; };
|
625CB5772678C34300530A6E /* ConnectToServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 625CB5762678C34300530A6E /* ConnectToServerViewModel.swift */; };
|
||||||
625CB57A2678C4A400530A6E /* ActivityIndicator in Frameworks */ = {isa = PBXBuildFile; productRef = 625CB5792678C4A400530A6E /* ActivityIndicator */; };
|
625CB57A2678C4A400530A6E /* ActivityIndicator in Frameworks */ = {isa = PBXBuildFile; productRef = 625CB5792678C4A400530A6E /* ActivityIndicator */; };
|
||||||
6264E88A27384A6F0081A12A /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FCD08726C35A0D007C8DCF /* NetworkError.swift */; };
|
6264E88A27384A6F0081A12A /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FCD08726C35A0D007C8DCF /* NetworkError.swift */; };
|
||||||
|
6264E88C273850380081A12A /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6264E88B273850380081A12A /* Strings.swift */; };
|
||||||
|
6264E88D273850380081A12A /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6264E88B273850380081A12A /* Strings.swift */; };
|
||||||
|
6264E88E273850380081A12A /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6264E88B273850380081A12A /* Strings.swift */; };
|
||||||
62671DB327159C1800199D95 /* ItemCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0BF26D61C5000B8E046 /* ItemCoordinator.swift */; };
|
62671DB327159C1800199D95 /* ItemCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0BF26D61C5000B8E046 /* ItemCoordinator.swift */; };
|
||||||
6267B3D626710B8900A7371D /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6267B3D526710B8900A7371D /* CollectionExtensions.swift */; };
|
6267B3D626710B8900A7371D /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6267B3D526710B8900A7371D /* CollectionExtensions.swift */; };
|
||||||
6267B3D726710B9700A7371D /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6267B3D526710B8900A7371D /* CollectionExtensions.swift */; };
|
6267B3D726710B9700A7371D /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6267B3D526710B8900A7371D /* CollectionExtensions.swift */; };
|
||||||
|
@ -184,10 +186,6 @@
|
||||||
6267B3DA2671138200A7371D /* ImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6267B3D92671138200A7371D /* ImageExtensions.swift */; };
|
6267B3DA2671138200A7371D /* ImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6267B3D92671138200A7371D /* ImageExtensions.swift */; };
|
||||||
6267B3DB2671139400A7371D /* ImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6267B3D92671138200A7371D /* ImageExtensions.swift */; };
|
6267B3DB2671139400A7371D /* ImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6267B3D92671138200A7371D /* ImageExtensions.swift */; };
|
||||||
6267B3DC2671139500A7371D /* ImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6267B3D92671138200A7371D /* ImageExtensions.swift */; };
|
6267B3DC2671139500A7371D /* ImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6267B3D92671138200A7371D /* ImageExtensions.swift */; };
|
||||||
6286F0A1271C0AA500C40ED5 /* R.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6286F0A0271C0AA500C40ED5 /* R.generated.swift */; };
|
|
||||||
6286F0A2271C0AA500C40ED5 /* R.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6286F0A0271C0AA500C40ED5 /* R.generated.swift */; };
|
|
||||||
6286F0A6271C0EB700C40ED5 /* R.swift+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6286F0A5271C0EB700C40ED5 /* R.swift+SwiftUI.swift */; };
|
|
||||||
6286F0A7271C0EB700C40ED5 /* R.swift+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6286F0A5271C0EB700C40ED5 /* R.swift+SwiftUI.swift */; };
|
|
||||||
628B95242670CABD0091AF3B /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 628B95232670CABD0091AF3B /* SwiftUI.framework */; };
|
628B95242670CABD0091AF3B /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 628B95232670CABD0091AF3B /* SwiftUI.framework */; };
|
||||||
628B95272670CABD0091AF3B /* NextUpWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 628B95262670CABD0091AF3B /* NextUpWidget.swift */; };
|
628B95272670CABD0091AF3B /* NextUpWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 628B95262670CABD0091AF3B /* NextUpWidget.swift */; };
|
||||||
628B95292670CABE0091AF3B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 628B95282670CABE0091AF3B /* Assets.xcassets */; };
|
628B95292670CABE0091AF3B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 628B95282670CABE0091AF3B /* Assets.xcassets */; };
|
||||||
|
@ -521,10 +519,9 @@
|
||||||
625CB5762678C34300530A6E /* ConnectToServerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectToServerViewModel.swift; sourceTree = "<group>"; };
|
625CB5762678C34300530A6E /* ConnectToServerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectToServerViewModel.swift; sourceTree = "<group>"; };
|
||||||
625CB57B2678CE1000530A6E /* ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = "<group>"; };
|
625CB57B2678CE1000530A6E /* ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = "<group>"; };
|
||||||
625CB57D2678E81E00530A6E /* TVVLCKit.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = TVVLCKit.xcframework; path = Carthage/Build/TVVLCKit.xcframework; sourceTree = "<group>"; };
|
625CB57D2678E81E00530A6E /* TVVLCKit.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = TVVLCKit.xcframework; path = Carthage/Build/TVVLCKit.xcframework; sourceTree = "<group>"; };
|
||||||
|
6264E88B273850380081A12A /* Strings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
|
||||||
6267B3D526710B8900A7371D /* CollectionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExtensions.swift; sourceTree = "<group>"; };
|
6267B3D526710B8900A7371D /* CollectionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExtensions.swift; sourceTree = "<group>"; };
|
||||||
6267B3D92671138200A7371D /* ImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageExtensions.swift; sourceTree = "<group>"; };
|
6267B3D92671138200A7371D /* ImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageExtensions.swift; sourceTree = "<group>"; };
|
||||||
6286F0A0271C0AA500C40ED5 /* R.generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = R.generated.swift; sourceTree = "<group>"; };
|
|
||||||
6286F0A5271C0EB700C40ED5 /* R.swift+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "R.swift+SwiftUI.swift"; sourceTree = "<group>"; };
|
|
||||||
628B95202670CABD0091AF3B /* WidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
628B95202670CABD0091AF3B /* WidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
628B95212670CABD0091AF3B /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
|
628B95212670CABD0091AF3B /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
|
||||||
628B95232670CABD0091AF3B /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
|
628B95232670CABD0091AF3B /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
|
||||||
|
@ -1069,7 +1066,6 @@
|
||||||
621338922660107500A81A2A /* StringExtensions.swift */,
|
621338922660107500A81A2A /* StringExtensions.swift */,
|
||||||
E13DD3C727164B1E009D4DAF /* UIDeviceExtensions.swift */,
|
E13DD3C727164B1E009D4DAF /* UIDeviceExtensions.swift */,
|
||||||
6220D0AC26D5EABB00B8E046 /* ViewExtensions.swift */,
|
6220D0AC26D5EABB00B8E046 /* ViewExtensions.swift */,
|
||||||
6286F0A5271C0EB700C40ED5 /* R.swift+SwiftUI.swift */,
|
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1077,7 +1073,7 @@
|
||||||
6286F09F271C0AA500C40ED5 /* Generated */ = {
|
6286F09F271C0AA500C40ED5 /* Generated */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
6286F0A0271C0AA500C40ED5 /* R.generated.swift */,
|
6264E88B273850380081A12A /* Strings.swift */,
|
||||||
);
|
);
|
||||||
path = Generated;
|
path = Generated;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1648,17 +1644,15 @@
|
||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"$TEMP_DIR/rswift-lastrun",
|
|
||||||
);
|
);
|
||||||
name = R.swift;
|
name = R.swift;
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
);
|
);
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
$SRCROOT/Shared/Generated/R.generated.swift,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nif [ $ACTION != \"indexbuild\" ]; then\n \"$PODS_ROOT/R.swift/rswift\" generate \"$SRCROOT/Shared/Generated/R.generated.swift\" --generators string\nfi\n";
|
shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\"${PROJECT_DIR}/bin/swiftgen\"\n";
|
||||||
};
|
};
|
||||||
6286F0A3271C0ABA00C40ED5 /* R.swift */ = {
|
6286F0A3271C0ABA00C40ED5 /* R.swift */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
@ -1668,17 +1662,15 @@
|
||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"$TEMP_DIR/rswift-lastrun",
|
|
||||||
);
|
);
|
||||||
name = R.swift;
|
name = R.swift;
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
);
|
);
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
$SRCROOT/Shared/Generated/R.generated.swift,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nif [ $ACTION != \"indexbuild\" ]; then\n \"$PODS_ROOT/R.swift/rswift\" generate \"$SRCROOT/Shared/Generated/R.generated.swift\" --generators string\nfi\n";
|
shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\"${PROJECT_DIR}/bin/swiftgen\"\n";
|
||||||
};
|
};
|
||||||
879C22C1CCC48E68C86E904C /* [CP] Embed Pods Frameworks */ = {
|
879C22C1CCC48E68C86E904C /* [CP] Embed Pods Frameworks */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
@ -1786,7 +1778,6 @@
|
||||||
53CD2A40268A49C2002ABD4E /* ItemView.swift in Sources */,
|
53CD2A40268A49C2002ABD4E /* ItemView.swift in Sources */,
|
||||||
53CD2A42268A4B38002ABD4E /* MovieItemView.swift in Sources */,
|
53CD2A42268A4B38002ABD4E /* MovieItemView.swift in Sources */,
|
||||||
536D3D7F267BDF100004248C /* LatestMediaView.swift in Sources */,
|
536D3D7F267BDF100004248C /* LatestMediaView.swift in Sources */,
|
||||||
6286F0A7271C0EB700C40ED5 /* R.swift+SwiftUI.swift in Sources */,
|
|
||||||
091B5A8E268315D400D78B61 /* UDPBroadCastConnection.swift in Sources */,
|
091B5A8E268315D400D78B61 /* UDPBroadCastConnection.swift in Sources */,
|
||||||
E1FCD08926C35A0D007C8DCF /* NetworkError.swift in Sources */,
|
E1FCD08926C35A0D007C8DCF /* NetworkError.swift in Sources */,
|
||||||
531690ED267ABF46005D8AB9 /* ContinueWatchingView.swift in Sources */,
|
531690ED267ABF46005D8AB9 /* ContinueWatchingView.swift in Sources */,
|
||||||
|
@ -1819,7 +1810,6 @@
|
||||||
E1D4BF852719D25A00A11E64 /* TrackLanguage.swift in Sources */,
|
E1D4BF852719D25A00A11E64 /* TrackLanguage.swift in Sources */,
|
||||||
53272532268BF09D0035FBF1 /* MediaViewActionButton.swift in Sources */,
|
53272532268BF09D0035FBF1 /* MediaViewActionButton.swift in Sources */,
|
||||||
531690F0267ABF72005D8AB9 /* NextUpView.swift in Sources */,
|
531690F0267ABF72005D8AB9 /* NextUpView.swift in Sources */,
|
||||||
6286F0A2271C0AA500C40ED5 /* R.generated.swift in Sources */,
|
|
||||||
E193D53427193F7F00900D82 /* HomeCoordinator.swift in Sources */,
|
E193D53427193F7F00900D82 /* HomeCoordinator.swift in Sources */,
|
||||||
E193D5502719430400900D82 /* ServerDetailView.swift in Sources */,
|
E193D5502719430400900D82 /* ServerDetailView.swift in Sources */,
|
||||||
E11B1B6D2718CD68006DA3E8 /* JellyfinAPIError.swift in Sources */,
|
E11B1B6D2718CD68006DA3E8 /* JellyfinAPIError.swift in Sources */,
|
||||||
|
@ -1857,6 +1847,7 @@
|
||||||
5321753E2671DE9C005491E6 /* Typings.swift in Sources */,
|
5321753E2671DE9C005491E6 /* Typings.swift in Sources */,
|
||||||
E1F0204F26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */,
|
E1F0204F26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */,
|
||||||
53ABFDEB2679753200886593 /* ConnectToServerView.swift in Sources */,
|
53ABFDEB2679753200886593 /* ConnectToServerView.swift in Sources */,
|
||||||
|
6264E88D273850380081A12A /* Strings.swift in Sources */,
|
||||||
536D3D76267BA9BB0004248C /* MainTabViewModel.swift in Sources */,
|
536D3D76267BA9BB0004248C /* MainTabViewModel.swift in Sources */,
|
||||||
E193D5512719432400900D82 /* ServerDetailViewModel.swift in Sources */,
|
E193D5512719432400900D82 /* ServerDetailViewModel.swift in Sources */,
|
||||||
5310695C2684E7EE00CFFDBA /* VideoPlayerViewController.swift in Sources */,
|
5310695C2684E7EE00CFFDBA /* VideoPlayerViewController.swift in Sources */,
|
||||||
|
@ -1927,6 +1918,7 @@
|
||||||
625CB56F2678C23300530A6E /* HomeView.swift in Sources */,
|
625CB56F2678C23300530A6E /* HomeView.swift in Sources */,
|
||||||
E173DA5226D04AAF00CC4EB7 /* ColorExtension.swift in Sources */,
|
E173DA5226D04AAF00CC4EB7 /* ColorExtension.swift in Sources */,
|
||||||
53892770263C25230035E14B /* NextUpView.swift in Sources */,
|
53892770263C25230035E14B /* NextUpView.swift in Sources */,
|
||||||
|
6264E88C273850380081A12A /* Strings.swift in Sources */,
|
||||||
C4BE0766271FC109003F4AD1 /* TVLibrariesViewModel.swift in Sources */,
|
C4BE0766271FC109003F4AD1 /* TVLibrariesViewModel.swift in Sources */,
|
||||||
62ECA01826FA685A00E8EBB7 /* DeepLink.swift in Sources */,
|
62ECA01826FA685A00E8EBB7 /* DeepLink.swift in Sources */,
|
||||||
535BAEA5264A151C005FA86D /* VideoPlayer.swift in Sources */,
|
535BAEA5264A151C005FA86D /* VideoPlayer.swift in Sources */,
|
||||||
|
@ -1940,7 +1932,6 @@
|
||||||
53DF641E263D9C0600A7CD1A /* LibraryView.swift in Sources */,
|
53DF641E263D9C0600A7CD1A /* LibraryView.swift in Sources */,
|
||||||
E188460026DECB9E00B0C5B7 /* ItemLandscapeTopBarView.swift in Sources */,
|
E188460026DECB9E00B0C5B7 /* ItemLandscapeTopBarView.swift in Sources */,
|
||||||
091B5A8B2683142E00D78B61 /* UDPBroadCastConnection.swift in Sources */,
|
091B5A8B2683142E00D78B61 /* UDPBroadCastConnection.swift in Sources */,
|
||||||
6286F0A1271C0AA500C40ED5 /* R.generated.swift in Sources */,
|
|
||||||
6267B3D626710B8900A7371D /* CollectionExtensions.swift in Sources */,
|
6267B3D626710B8900A7371D /* CollectionExtensions.swift in Sources */,
|
||||||
E13DD3F5271793BB009D4DAF /* UserSignInView.swift in Sources */,
|
E13DD3F5271793BB009D4DAF /* UserSignInView.swift in Sources */,
|
||||||
E1F0204E26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */,
|
E1F0204E26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */,
|
||||||
|
@ -1962,7 +1953,6 @@
|
||||||
E1D4BF812719D22800A11E64 /* AppAppearance.swift in Sources */,
|
E1D4BF812719D22800A11E64 /* AppAppearance.swift in Sources */,
|
||||||
621338B32660A07800A81A2A /* LazyView.swift in Sources */,
|
621338B32660A07800A81A2A /* LazyView.swift in Sources */,
|
||||||
6220D0B126D5EC9900B8E046 /* SettingsCoordinator.swift in Sources */,
|
6220D0B126D5EC9900B8E046 /* SettingsCoordinator.swift in Sources */,
|
||||||
6286F0A6271C0EB700C40ED5 /* R.swift+SwiftUI.swift in Sources */,
|
|
||||||
62C29EA626D1036A00C1D2E7 /* HomeCoordinator.swift in Sources */,
|
62C29EA626D1036A00C1D2E7 /* HomeCoordinator.swift in Sources */,
|
||||||
531AC8BF26750DE20091C7EB /* ImageView.swift in Sources */,
|
531AC8BF26750DE20091C7EB /* ImageView.swift in Sources */,
|
||||||
E13DD3E927177ED6009D4DAF /* ServerListCoordinator.swift in Sources */,
|
E13DD3E927177ED6009D4DAF /* ServerListCoordinator.swift in Sources */,
|
||||||
|
@ -2025,10 +2015,10 @@
|
||||||
E1AD105926D9A543003E4A08 /* LazyView.swift in Sources */,
|
E1AD105926D9A543003E4A08 /* LazyView.swift in Sources */,
|
||||||
E11B1B6E2718CDBA006DA3E8 /* JellyfinAPIError.swift in Sources */,
|
E11B1B6E2718CDBA006DA3E8 /* JellyfinAPIError.swift in Sources */,
|
||||||
628B95372670CB800091AF3B /* JellyfinWidget.swift in Sources */,
|
628B95372670CB800091AF3B /* JellyfinWidget.swift in Sources */,
|
||||||
|
6264E88E273850380081A12A /* Strings.swift in Sources */,
|
||||||
E1AD105426D97161003E4A08 /* BaseItemDtoExtensions.swift in Sources */,
|
E1AD105426D97161003E4A08 /* BaseItemDtoExtensions.swift in Sources */,
|
||||||
E1FCD09A26C4F35A007C8DCF /* ErrorMessage.swift in Sources */,
|
E1FCD09A26C4F35A007C8DCF /* ErrorMessage.swift in Sources */,
|
||||||
628B95272670CABD0091AF3B /* NextUpWidget.swift in Sources */,
|
628B95272670CABD0091AF3B /* NextUpWidget.swift in Sources */,
|
||||||
62167B882738411700167ECE /* R.generated.swift in Sources */,
|
|
||||||
E13DD3F72717E87D009D4DAF /* SwiftfinNotificationCenter.swift in Sources */,
|
E13DD3F72717E87D009D4DAF /* SwiftfinNotificationCenter.swift in Sources */,
|
||||||
E1D4BF8D2719F3A300A11E64 /* VideoPlayerJumpLength.swift in Sources */,
|
E1D4BF8D2719F3A300A11E64 /* VideoPlayerJumpLength.swift in Sources */,
|
||||||
6220D0AF26D5EABE00B8E046 /* ViewExtensions.swift in Sources */,
|
6220D0AF26D5EABE00B8E046 /* ViewExtensions.swift in Sources */,
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>DisableBuildSystemDeprecationDiagnostic</key>
|
||||||
|
<true/>
|
||||||
|
<key>PreviewsEnabled</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -75,7 +75,7 @@ struct PortraitItemView: View {
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
} else {
|
} else {
|
||||||
Text(R.string.localizable.seasonAndEpisode(String(item.parentIndexNumber ?? 0), String(item.indexNumber ?? 0))
|
Text(L10n.seasonAndEpisode(String(item.parentIndexNumber ?? 0), String(item.indexNumber ?? 0)))
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
|
|
|
@ -23,7 +23,7 @@ struct BasicAppSettingsView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
Section {
|
Section {
|
||||||
Picker(R.string.localizable.appearance(), selection: $appAppearance) {
|
Picker(L10n.appearance, selection: $appAppearance) {
|
||||||
ForEach(self.viewModel.appearances, id: \.self) { appearance in
|
ForEach(self.viewModel.appearances, id: \.self) { appearance in
|
||||||
Text(appearance.localizedName).tag(appearance.rawValue)
|
Text(appearance.localizedName).tag(appearance.rawValue)
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ struct BasicAppSettingsView: View {
|
||||||
UIApplication.shared.windows.first?.overrideUserInterfaceStyle = appAppearance.style
|
UIApplication.shared.windows.first?.overrideUserInterfaceStyle = appAppearance.style
|
||||||
})
|
})
|
||||||
} header: {
|
} header: {
|
||||||
R.string.localizable.accessibility.text
|
L10n.accessibility.text
|
||||||
}
|
}
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
|
@ -47,15 +47,15 @@ struct BasicAppSettingsView: View {
|
||||||
Button {
|
Button {
|
||||||
resetTapped = true
|
resetTapped = true
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.reset.text
|
L10n.reset.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.alert(R.string.localizable.reset(), isPresented: $resetTapped, actions: {
|
.alert(L10n.reset, isPresented: $resetTapped, actions: {
|
||||||
Button(role: .destructive) {
|
Button(role: .destructive) {
|
||||||
viewModel.reset()
|
viewModel.reset()
|
||||||
basicAppSettingsRouter.dismissCoordinator()
|
basicAppSettingsRouter.dismissCoordinator()
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.reset.text
|
L10n.reset.text
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.navigationBarTitle("Settings", displayMode: .inline)
|
.navigationBarTitle("Settings", displayMode: .inline)
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct ConnectToServerView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
List {
|
||||||
Section {
|
Section {
|
||||||
TextField(R.string.localizable.serverURL(), text: $uri)
|
TextField(L10n.serverURL, text: $uri)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.keyboardType(.URL)
|
.keyboardType(.URL)
|
||||||
|
@ -40,7 +40,7 @@ struct ConnectToServerView: View {
|
||||||
Button {
|
Button {
|
||||||
viewModel.connectToServer(uri: uri)
|
viewModel.connectToServer(uri: uri)
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.connect.text
|
L10n.connect.text
|
||||||
}
|
}
|
||||||
.disabled(uri.isEmpty)
|
.disabled(uri.isEmpty)
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ struct ConnectToServerView: View {
|
||||||
}
|
}
|
||||||
} header: {
|
} header: {
|
||||||
HStack {
|
HStack {
|
||||||
R.string.localizable.localServers.text
|
L10n.localServers.text
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
|
@ -106,7 +106,7 @@ struct ConnectToServerView: View {
|
||||||
message: Text(viewModel.errorMessage?.displayMessage ?? "Unknown Error"),
|
message: Text(viewModel.errorMessage?.displayMessage ?? "Unknown Error"),
|
||||||
dismissButton: .cancel())
|
dismissButton: .cancel())
|
||||||
}
|
}
|
||||||
.navigationTitle(R.string.localizable.connect())
|
.navigationTitle(L10n.connect)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
viewModel.discoverServers()
|
viewModel.discoverServers()
|
||||||
AppURLHandler.shared.appURLState = .allowedInLogin
|
AppURLHandler.shared.appURLState = .allowedInLogin
|
||||||
|
|
|
@ -34,7 +34,7 @@ struct HomeView: View {
|
||||||
|
|
||||||
ForEach(viewModel.libraries, id: \.self) { library in
|
ForEach(viewModel.libraries, id: \.self) { library in
|
||||||
HStack {
|
HStack {
|
||||||
Text(R.string.localizable.latestWithString(library.name ?? ""))
|
Text(L10n.latestWithString(library.name ?? ""))
|
||||||
.font(.title2)
|
.font(.title2)
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
Spacer()
|
Spacer()
|
||||||
|
@ -45,7 +45,7 @@ struct HomeView: View {
|
||||||
title: library.name ?? ""))
|
title: library.name ?? ""))
|
||||||
} label: {
|
} label: {
|
||||||
HStack {
|
HStack {
|
||||||
R.string.localizable.seeAll.text.font(.subheadline).fontWeight(.bold)
|
L10n.seeAll.text.font(.subheadline).fontWeight(.bold)
|
||||||
Image(systemName: "chevron.right").font(Font.subheadline.bold())
|
Image(systemName: "chevron.right").font(Font.subheadline.bold())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ struct HomeView: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
innerBody
|
innerBody
|
||||||
.navigationTitle(R.string.localizable.home())
|
.navigationTitle(L10n.home)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
||||||
Button {
|
Button {
|
||||||
|
|
|
@ -29,7 +29,7 @@ struct ItemViewBody: View {
|
||||||
PortraitImageHStackView(items: seriesViewModel.seasons,
|
PortraitImageHStackView(items: seriesViewModel.seasons,
|
||||||
maxWidth: 150,
|
maxWidth: 150,
|
||||||
topBarView: {
|
topBarView: {
|
||||||
R.string.localizable.seasons.text
|
L10n.seasons.text
|
||||||
.font(.callout)
|
.font(.callout)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.padding(.top, 3)
|
.padding(.top, 3)
|
||||||
|
@ -41,7 +41,7 @@ struct ItemViewBody: View {
|
||||||
|
|
||||||
// MARK: Genres
|
// MARK: Genres
|
||||||
|
|
||||||
PillHStackView(title: R.string.localizable.genres(),
|
PillHStackView(title: L10n.genres,
|
||||||
items: viewModel.item.genreItems ?? [],
|
items: viewModel.item.genreItems ?? [],
|
||||||
selectedAction: { genre in
|
selectedAction: { genre in
|
||||||
itemRouter.route(to: \.library, (viewModel: .init(genre: genre), title: genre.title))
|
itemRouter.route(to: \.library, (viewModel: .init(genre: genre), title: genre.title))
|
||||||
|
@ -50,7 +50,7 @@ struct ItemViewBody: View {
|
||||||
// MARK: Studios
|
// MARK: Studios
|
||||||
|
|
||||||
if let studios = viewModel.item.studios {
|
if let studios = viewModel.item.studios {
|
||||||
PillHStackView(title: R.string.localizable.studios(),
|
PillHStackView(title: L10n.studios,
|
||||||
items: studios) { studio in
|
items: studios) { studio in
|
||||||
itemRouter.route(to: \.library, (viewModel: .init(studio: studio), title: studio.name ?? ""))
|
itemRouter.route(to: \.library, (viewModel: .init(studio: studio), title: studio.name ?? ""))
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ struct ItemViewBody: View {
|
||||||
PortraitImageHStackView(items: viewModel.similarItems,
|
PortraitImageHStackView(items: viewModel.similarItems,
|
||||||
maxWidth: 150,
|
maxWidth: 150,
|
||||||
topBarView: {
|
topBarView: {
|
||||||
R.string.localizable.moreLikeThis.text
|
L10n.moreLikeThis.text
|
||||||
.font(.callout)
|
.font(.callout)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.padding(.top, 3)
|
.padding(.top, 3)
|
||||||
|
|
|
@ -31,32 +31,32 @@ struct LibraryFilterView: View {
|
||||||
} else {
|
} else {
|
||||||
Form {
|
Form {
|
||||||
if viewModel.enabledFilterType.contains(.genre) {
|
if viewModel.enabledFilterType.contains(.genre) {
|
||||||
MultiSelector(label: R.string.localizable.genres(),
|
MultiSelector(label: L10n.genres,
|
||||||
options: viewModel.possibleGenres,
|
options: viewModel.possibleGenres,
|
||||||
optionToString: { $0.name ?? "" },
|
optionToString: { $0.name ?? "" },
|
||||||
selected: $viewModel.modifiedFilters.withGenres)
|
selected: $viewModel.modifiedFilters.withGenres)
|
||||||
}
|
}
|
||||||
if viewModel.enabledFilterType.contains(.filter) {
|
if viewModel.enabledFilterType.contains(.filter) {
|
||||||
MultiSelector(label: R.string.localizable.filters(),
|
MultiSelector(label: L10n.filters,
|
||||||
options: viewModel.possibleItemFilters,
|
options: viewModel.possibleItemFilters,
|
||||||
optionToString: { $0.localized },
|
optionToString: { $0.localized },
|
||||||
selected: $viewModel.modifiedFilters.filters)
|
selected: $viewModel.modifiedFilters.filters)
|
||||||
}
|
}
|
||||||
if viewModel.enabledFilterType.contains(.tag) {
|
if viewModel.enabledFilterType.contains(.tag) {
|
||||||
MultiSelector(label: R.string.localizable.tags(),
|
MultiSelector(label: L10n.tags,
|
||||||
options: viewModel.possibleTags,
|
options: viewModel.possibleTags,
|
||||||
optionToString: { $0 },
|
optionToString: { $0 },
|
||||||
selected: $viewModel.modifiedFilters.tags)
|
selected: $viewModel.modifiedFilters.tags)
|
||||||
}
|
}
|
||||||
if viewModel.enabledFilterType.contains(.sortBy) {
|
if viewModel.enabledFilterType.contains(.sortBy) {
|
||||||
Picker(selection: $viewModel.selectedSortBy, label: R.string.localizable.sortBy.text) {
|
Picker(selection: $viewModel.selectedSortBy, label: L10n.sortBy.text) {
|
||||||
ForEach(viewModel.possibleSortBys, id: \.self) { so in
|
ForEach(viewModel.possibleSortBys, id: \.self) { so in
|
||||||
Text(so.localized).tag(so)
|
Text(so.localized).tag(so)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if viewModel.enabledFilterType.contains(.sortOrder) {
|
if viewModel.enabledFilterType.contains(.sortOrder) {
|
||||||
Picker(selection: $viewModel.selectedSortOrder, label: R.string.localizable.displayOrder.text) {
|
Picker(selection: $viewModel.selectedSortOrder, label: L10n.displayOrder.text) {
|
||||||
ForEach(viewModel.possibleSortOrders, id: \.self) { so in
|
ForEach(viewModel.possibleSortOrders, id: \.self) { so in
|
||||||
Text(so.rawValue).tag(so)
|
Text(so.rawValue).tag(so)
|
||||||
}
|
}
|
||||||
|
@ -68,11 +68,11 @@ struct LibraryFilterView: View {
|
||||||
self.filters = viewModel.modifiedFilters
|
self.filters = viewModel.modifiedFilters
|
||||||
filterRouter.dismissCoordinator()
|
filterRouter.dismissCoordinator()
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.reset.text
|
L10n.reset.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationBarTitle(R.string.localizable.filterResults(), displayMode: .inline)
|
.navigationBarTitle(L10n.filterResults, displayMode: .inline)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItemGroup(placement: .navigationBarLeading) {
|
ToolbarItemGroup(placement: .navigationBarLeading) {
|
||||||
Button {
|
Button {
|
||||||
|
@ -87,7 +87,7 @@ struct LibraryFilterView: View {
|
||||||
self.filters = viewModel.modifiedFilters
|
self.filters = viewModel.modifiedFilters
|
||||||
filterRouter.dismissCoordinator()
|
filterRouter.dismissCoordinator()
|
||||||
} label: {
|
} label: {
|
||||||
R.string.localizable.apply.text
|
L10n.apply.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ struct LibraryListView: View {
|
||||||
ZStack {
|
ZStack {
|
||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
R.string.localizable.yourFavorites.text
|
L10n.yourFavorites.text
|
||||||
.foregroundColor(.black)
|
.foregroundColor(.black)
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
|
@ -39,12 +39,12 @@ struct LibraryListView: View {
|
||||||
.padding(.bottom, 5)
|
.padding(.bottom, 5)
|
||||||
|
|
||||||
NavigationLink(destination: LazyView {
|
NavigationLink(destination: LazyView {
|
||||||
R.string.localizable.wip.text
|
L10n.wip.text
|
||||||
}) {
|
}) {
|
||||||
ZStack {
|
ZStack {
|
||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
R.string.localizable.allGenres.text
|
L10n.allGenres.text
|
||||||
.foregroundColor(.black)
|
.foregroundColor(.black)
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
|
@ -98,7 +98,7 @@ struct LibraryListView: View {
|
||||||
.padding(.trailing, 16)
|
.padding(.trailing, 16)
|
||||||
.padding(.top, 8)
|
.padding(.top, 8)
|
||||||
}
|
}
|
||||||
.navigationTitle(R.string.localizable.allMedia())
|
.navigationTitle(L10n.allMedia)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
||||||
Button {
|
Button {
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct LibrarySearchView: View {
|
||||||
var suggestionsListView: some View {
|
var suggestionsListView: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
LazyVStack(spacing: 8) {
|
LazyVStack(spacing: 8) {
|
||||||
R.string.localizable.suggestions.text
|
L10n.suggestions.text
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
|
|
@ -55,7 +55,7 @@ struct LibraryView: View {
|
||||||
Image(systemName: "chevron.left")
|
Image(systemName: "chevron.left")
|
||||||
.font(.system(size: 25))
|
.font(.system(size: 25))
|
||||||
}.disabled(!viewModel.hasPreviousPage)
|
}.disabled(!viewModel.hasPreviousPage)
|
||||||
Text(R.string.localizable.pageOfWithNumbers(String(viewModel.currentPage + 1), String(viewModel.totalPages)))
|
Text(L10n.pageOfWithNumbers(String(viewModel.currentPage + 1), String(viewModel.totalPages)))
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
Button {
|
Button {
|
||||||
|
@ -72,7 +72,7 @@ struct LibraryView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
R.string.localizable.noResults.text
|
L10n.noResults.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationBarTitle(title, displayMode: .inline)
|
.navigationBarTitle(title, displayMode: .inline)
|
||||||
|
|
|
@ -32,7 +32,7 @@ struct LoadingView<Content>: View where Content: View {
|
||||||
// indicator, with some text underneath showing what we are doing
|
// indicator, with some text underneath showing what we are doing
|
||||||
HStack {
|
HStack {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
Text(text ?? R.string.localizable.loading()).fontWeight(.semibold).font(.callout).offset(x: 60)
|
Text(text ?? L10n.loading).fontWeight(.semibold).font(.callout).offset(x: 60)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
.padding(EdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 10))
|
.padding(EdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 10))
|
||||||
|
@ -70,7 +70,7 @@ struct LoadingViewNoBlur<Content>: View where Content: View {
|
||||||
// indicator, with some text underneath showing what we are doing
|
// indicator, with some text underneath showing what we are doing
|
||||||
HStack {
|
HStack {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
Text(text ?? R.string.localizable.loading()).fontWeight(.semibold).font(.callout).offset(x: 60)
|
Text(text ?? L10n.loading).fontWeight(.semibold).font(.callout).offset(x: 60)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
.padding(EdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 10))
|
.padding(EdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 10))
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct NextUpView: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
R.string.localizable.nextUp.text
|
L10n.nextUp.text
|
||||||
.font(.title2)
|
.font(.title2)
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
.padding(.leading, 16)
|
.padding(.leading, 16)
|
||||||
|
|
|
@ -81,7 +81,7 @@ struct ServerListView: View {
|
||||||
.padding(.horizontal, 30)
|
.padding(.horizontal, 30)
|
||||||
.padding([.top, .bottom], 20)
|
.padding([.top, .bottom], 20)
|
||||||
|
|
||||||
R.string.localizable.connect.text
|
L10n.connect.text
|
||||||
.foregroundColor(Color.white)
|
.foregroundColor(Color.white)
|
||||||
.bold()
|
.bold()
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ struct SettingsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: R.string.localizable.accessibility.text) {
|
Section(header: L10n.accessibility.text) {
|
||||||
Toggle("Automatically show subtitles", isOn: $isAutoSelectSubtitles)
|
Toggle("Automatically show subtitles", isOn: $isAutoSelectSubtitles)
|
||||||
SearchablePicker(label: "Preferred subtitle language",
|
SearchablePicker(label: "Preferred subtitle language",
|
||||||
options: viewModel.langs,
|
options: viewModel.langs,
|
||||||
|
@ -129,7 +129,7 @@ struct SettingsView: View {
|
||||||
.auto
|
.auto
|
||||||
},
|
},
|
||||||
set: { autoSelectAudioLangcode = $0.isoCode }))
|
set: { autoSelectAudioLangcode = $0.isoCode }))
|
||||||
Picker(R.string.localizable.appearance(), selection: $appAppearance) {
|
Picker(L10n.appearance, selection: $appAppearance) {
|
||||||
ForEach(self.viewModel.appearances, id: \.self) { appearance in
|
ForEach(self.viewModel.appearances, id: \.self) { appearance in
|
||||||
Text(appearance.localizedName).tag(appearance.rawValue)
|
Text(appearance.localizedName).tag(appearance.rawValue)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ struct UserSignInView: View {
|
||||||
Form {
|
Form {
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
TextField(R.string.localizable.username(), text: $username)
|
TextField(L10n.username, text: $username)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
|
|
||||||
SecureField(R.string.localizable.password(), text: $password)
|
SecureField(L10n.password, text: $password)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
|
|
||||||
|
|
|
@ -421,7 +421,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
|
||||||
if manifest.type == "Movie" {
|
if manifest.type == "Movie" {
|
||||||
titleLabel.text = manifest.name ?? ""
|
titleLabel.text = manifest.name ?? ""
|
||||||
} else {
|
} else {
|
||||||
titleLabel.text = "\(R.string.localizable.seasonAndEpisode(String(manifest.parentIndexNumber ?? 0), String(manifest.indexNumber ?? 0))) “\(manifest.name ?? "")”"
|
titleLabel.text = "\(L10n.seasonAndEpisode(String(manifest.parentIndexNumber ?? 0), String(manifest.indexNumber ?? 0))) “\(manifest.name ?? "")”"
|
||||||
|
|
||||||
setupNextUpView()
|
setupNextUpView()
|
||||||
upNextViewModel.delegate = self
|
upNextViewModel.delegate = self
|
||||||
|
@ -816,7 +816,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
|
||||||
shouldShowLoadingScreen = true
|
shouldShowLoadingScreen = true
|
||||||
videoControlsView.isHidden = true
|
videoControlsView.isHidden = true
|
||||||
|
|
||||||
titleLabel.text = "\(R.string.localizable.seasonAndEpisode(String(manifest.parentIndexNumber ?? 0), String(manifest.indexNumber ?? 0))) “\(manifest.name ?? "")”"
|
titleLabel.text = "\(L10n.seasonAndEpisode(String(manifest.parentIndexNumber ?? 0), String(manifest.indexNumber ?? 0))) “\(manifest.name ?? "")”"
|
||||||
|
|
||||||
setupMediaPlayer()
|
setupMediaPlayer()
|
||||||
getNextEpisode()
|
getNextEpisode()
|
||||||
|
|
|
@ -56,7 +56,7 @@ struct VideoPlayerCastDeviceSelector: View {
|
||||||
delegate?.castPopoverDismissed()
|
delegate?.castPopoverDismissed()
|
||||||
} label: {
|
} label: {
|
||||||
HStack {
|
HStack {
|
||||||
R.string.localizable.connect.text
|
L10n.connect.text
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
Image(systemName: "bonjour")
|
Image(systemName: "bonjour")
|
||||||
|
@ -66,14 +66,14 @@ struct VideoPlayerCastDeviceSelector: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
R.string.localizable.noCastdevicesfound.text
|
L10n.noCastdevicesfound.text
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.navigationTitle(R.string.localizable.selectCastDestination())
|
.navigationTitle(L10n.selectCastDestination)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItemGroup(placement: .navigationBarLeading) {
|
ToolbarItemGroup(placement: .navigationBarLeading) {
|
||||||
if UIDevice.current.userInterfaceIdiom == .phone {
|
if UIDevice.current.userInterfaceIdiom == .phone {
|
||||||
|
@ -82,7 +82,7 @@ struct VideoPlayerCastDeviceSelector: View {
|
||||||
} label: {
|
} label: {
|
||||||
HStack {
|
HStack {
|
||||||
Image(systemName: "chevron.left")
|
Image(systemName: "chevron.left")
|
||||||
R.string.localizable.back.text.font(.callout)
|
L10n.back.text.font(.callout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ struct VideoPlayerSettings: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
Picker(R.string.localizable.closedCaptions(), selection: $captionTrack) {
|
Picker(L10n.closedCaptions, selection: $captionTrack) {
|
||||||
ForEach(delegate.subtitleTrackArray, id: \.id) { caption in
|
ForEach(delegate.subtitleTrackArray, id: \.id) { caption in
|
||||||
Text(caption.name).tag(caption.id)
|
Text(caption.name).tag(caption.id)
|
||||||
}
|
}
|
||||||
|
@ -48,14 +48,14 @@ struct VideoPlayerSettings: View {
|
||||||
.onChange(of: captionTrack) { track in
|
.onChange(of: captionTrack) { track in
|
||||||
self.delegate.subtitleTrackChanged(newTrackID: track)
|
self.delegate.subtitleTrackChanged(newTrackID: track)
|
||||||
}
|
}
|
||||||
Picker(R.string.localizable.audioTrack(), selection: $audioTrack) {
|
Picker(L10n.audioTrack, selection: $audioTrack) {
|
||||||
ForEach(delegate.audioTrackArray, id: \.id) { caption in
|
ForEach(delegate.audioTrackArray, id: \.id) { caption in
|
||||||
Text(caption.name).tag(caption.id).lineLimit(1)
|
Text(caption.name).tag(caption.id).lineLimit(1)
|
||||||
}
|
}
|
||||||
}.onChange(of: audioTrack) { track in
|
}.onChange(of: audioTrack) { track in
|
||||||
self.delegate.audioTrackChanged(newTrackID: track)
|
self.delegate.audioTrackChanged(newTrackID: track)
|
||||||
}
|
}
|
||||||
Picker(R.string.localizable.playbackSpeed(), selection: $playbackSpeedSelection) {
|
Picker(L10n.playbackSpeed, selection: $playbackSpeedSelection) {
|
||||||
ForEach(delegate.playbackSpeeds.indices, id: \.self) { speedIndex in
|
ForEach(delegate.playbackSpeeds.indices, id: \.self) { speedIndex in
|
||||||
let speed = delegate.playbackSpeeds[speedIndex]
|
let speed = delegate.playbackSpeeds[speedIndex]
|
||||||
Text("\(String(speed))x").tag(speedIndex)
|
Text("\(String(speed))x").tag(speedIndex)
|
||||||
|
@ -65,7 +65,7 @@ struct VideoPlayerSettings: View {
|
||||||
self.delegate.playbackSpeedChanged(index: index)
|
self.delegate.playbackSpeedChanged(index: index)
|
||||||
})
|
})
|
||||||
}.navigationBarTitleDisplayMode(.inline)
|
}.navigationBarTitleDisplayMode(.inline)
|
||||||
.navigationTitle(R.string.localizable.audioAndCaptions())
|
.navigationTitle(L10n.audioAndCaptions)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItemGroup(placement: .navigationBarLeading) {
|
ToolbarItemGroup(placement: .navigationBarLeading) {
|
||||||
if UIDevice.current.userInterfaceIdiom == .phone {
|
if UIDevice.current.userInterfaceIdiom == .phone {
|
||||||
|
@ -74,7 +74,7 @@ struct VideoPlayerSettings: View {
|
||||||
} label: {
|
} label: {
|
||||||
HStack {
|
HStack {
|
||||||
Image(systemName: "chevron.left")
|
Image(systemName: "chevron.left")
|
||||||
R.string.localizable.back.text.font(.callout)
|
L10n.back.text.font(.callout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ struct VideoUpNextView: View {
|
||||||
} label: {
|
} label: {
|
||||||
HStack {
|
HStack {
|
||||||
VStack {
|
VStack {
|
||||||
R.string.localizable.playNext.text
|
L10n.playNext.text
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
|
|
5
Podfile
5
Podfile
|
@ -1,7 +1,7 @@
|
||||||
use_frameworks!
|
use_frameworks!
|
||||||
inhibit_all_warnings!
|
inhibit_all_warnings!
|
||||||
def shared_pods
|
def shared_pods
|
||||||
pod 'R.swift'
|
pod 'SwiftGen'
|
||||||
end
|
end
|
||||||
|
|
||||||
target 'JellyfinPlayer iOS' do
|
target 'JellyfinPlayer iOS' do
|
||||||
|
@ -14,4 +14,7 @@ target 'JellyfinPlayer tvOS' do
|
||||||
platform :tvos, '14.0'
|
platform :tvos, '14.0'
|
||||||
shared_pods
|
shared_pods
|
||||||
pod 'TVVLCKit'
|
pod 'TVVLCKit'
|
||||||
|
end
|
||||||
|
target 'WidgetExtension' do
|
||||||
|
shared_pods
|
||||||
end
|
end
|
|
@ -26,7 +26,7 @@ final class MainTabCoordinator: TabCoordinatable {
|
||||||
|
|
||||||
@ViewBuilder func makeHomeTab(isActive: Bool) -> some View {
|
@ViewBuilder func makeHomeTab(isActive: Bool) -> some View {
|
||||||
Image(systemName: "house")
|
Image(systemName: "house")
|
||||||
R.string.localizable.home.text
|
L10n.home.text
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeAllMedia() -> NavigationViewCoordinator<LibraryListCoordinator> {
|
func makeAllMedia() -> NavigationViewCoordinator<LibraryListCoordinator> {
|
||||||
|
@ -35,7 +35,7 @@ final class MainTabCoordinator: TabCoordinatable {
|
||||||
|
|
||||||
@ViewBuilder func makeAllMediaTab(isActive: Bool) -> some View {
|
@ViewBuilder func makeAllMediaTab(isActive: Bool) -> some View {
|
||||||
Image(systemName: "folder")
|
Image(systemName: "folder")
|
||||||
R.string.localizable.allMedia.text
|
L10n.allMedia.text
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder func customize(_ view: AnyView) -> some View {
|
@ViewBuilder func customize(_ view: AnyView) -> some View {
|
||||||
|
|
|
@ -33,7 +33,7 @@ final class MainTabCoordinator: TabCoordinatable {
|
||||||
@ViewBuilder func makeHomeTab(isActive: Bool) -> some View {
|
@ViewBuilder func makeHomeTab(isActive: Bool) -> some View {
|
||||||
HStack {
|
HStack {
|
||||||
Image(systemName: "house")
|
Image(systemName: "house")
|
||||||
R.string.localizable.home.text
|
L10n.home.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,13 +85,13 @@ enum NetworkError: Error {
|
||||||
logMessage = "Cannot connect to host."
|
logMessage = "Cannot connect to host."
|
||||||
logConstructor.message = logMessage
|
logConstructor.message = logMessage
|
||||||
errorMessage = ErrorMessage(code: err._code,
|
errorMessage = ErrorMessage(code: err._code,
|
||||||
title: R.string.localizable.error(),
|
title: L10n.error,
|
||||||
displayMessage: displayMessage,
|
displayMessage: displayMessage,
|
||||||
logConstructor: logConstructor)
|
logConstructor: logConstructor)
|
||||||
default:
|
default:
|
||||||
logConstructor.message = logMessage
|
logConstructor.message = logMessage
|
||||||
errorMessage = ErrorMessage(code: err._code,
|
errorMessage = ErrorMessage(code: err._code,
|
||||||
title: R.string.localizable.error(),
|
title: L10n.error,
|
||||||
displayMessage: displayMessage,
|
displayMessage: displayMessage,
|
||||||
logConstructor: logConstructor)
|
logConstructor: logConstructor)
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ enum NetworkError: Error {
|
||||||
case .error:
|
case .error:
|
||||||
logConstructor.message = logMessage
|
logConstructor.message = logMessage
|
||||||
errorMessage = ErrorMessage(code: 0,
|
errorMessage = ErrorMessage(code: 0,
|
||||||
title: R.string.localizable.error(),
|
title: L10n.error,
|
||||||
displayMessage: displayMessage,
|
displayMessage: displayMessage,
|
||||||
logConstructor: logConstructor)
|
logConstructor: logConstructor)
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ enum NetworkError: Error {
|
||||||
default:
|
default:
|
||||||
logConstructor.message = logMessage
|
logConstructor.message = logMessage
|
||||||
errorMessage = ErrorMessage(code: code,
|
errorMessage = ErrorMessage(code: code,
|
||||||
title: R.string.localizable.error(),
|
title: L10n.error,
|
||||||
displayMessage: displayMessage,
|
displayMessage: displayMessage,
|
||||||
logConstructor: logConstructor)
|
logConstructor: logConstructor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ public extension BaseItemDto {
|
||||||
|
|
||||||
func getEpisodeLocator() -> String? {
|
func getEpisodeLocator() -> String? {
|
||||||
if let seasonNo = parentIndexNumber, let episodeNo = indexNumber {
|
if let seasonNo = parentIndexNumber, let episodeNo = indexNumber {
|
||||||
return R.string.localizable.seasonAndEpisode(String(seasonNo), String(episodeNo))
|
return L10n.seasonAndEpisode(String(seasonNo), String(episodeNo))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
//
|
|
||||||
/*
|
|
||||||
* SwiftFin is subject to the terms of the Mozilla Public
|
|
||||||
* License, v2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
*
|
|
||||||
* Copyright 2021 Aiden Vigue & Jellyfin Contributors
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Rswift
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
extension FontResource {
|
|
||||||
func font(size: CGFloat) -> Font {
|
|
||||||
Font.custom(fontName, size: size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ColorResource {
|
|
||||||
var color: Color {
|
|
||||||
Color(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension StringResource {
|
|
||||||
var localizedStringKey: LocalizedStringKey {
|
|
||||||
LocalizedStringKey(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
var text: Text {
|
|
||||||
Text(localizedStringKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ImageResource {
|
|
||||||
var image: Image {
|
|
||||||
Image(name)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
extension String {
|
extension String {
|
||||||
func removeRegexMatches(pattern: String, replaceWith: String = "") -> String {
|
func removeRegexMatches(pattern: String, replaceWith: String = "") -> String {
|
||||||
|
@ -31,4 +32,8 @@ extension String {
|
||||||
|
|
||||||
return "\(padString)\(self)"
|
return "\(padString)\(self)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var text: Text {
|
||||||
|
Text(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Strings
|
||||||
|
|
||||||
|
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
|
||||||
|
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
internal enum L10n {
|
||||||
|
/// Accessibility
|
||||||
|
internal static let accessibility = L10n.tr("Localizable", "accessibility")
|
||||||
|
/// All Genres
|
||||||
|
internal static let allGenres = L10n.tr("Localizable", "allGenres")
|
||||||
|
/// All Media
|
||||||
|
internal static let allMedia = L10n.tr("Localizable", "allMedia")
|
||||||
|
/// Appearance
|
||||||
|
internal static let appearance = L10n.tr("Localizable", "appearance")
|
||||||
|
/// Apply
|
||||||
|
internal static let apply = L10n.tr("Localizable", "apply")
|
||||||
|
/// Audio & Captions
|
||||||
|
internal static let audioAndCaptions = L10n.tr("Localizable", "audioAndCaptions")
|
||||||
|
/// Audio Track
|
||||||
|
internal static let audioTrack = L10n.tr("Localizable", "audioTrack")
|
||||||
|
/// Back
|
||||||
|
internal static let back = L10n.tr("Localizable", "back")
|
||||||
|
/// CAST
|
||||||
|
internal static let cast = L10n.tr("Localizable", "cast")
|
||||||
|
/// Change Server
|
||||||
|
internal static let changeServer = L10n.tr("Localizable", "changeServer")
|
||||||
|
/// Closed Captions
|
||||||
|
internal static let closedCaptions = L10n.tr("Localizable", "closedCaptions")
|
||||||
|
/// Connect
|
||||||
|
internal static let connect = L10n.tr("Localizable", "connect")
|
||||||
|
/// Connect Manually
|
||||||
|
internal static let connectManually = L10n.tr("Localizable", "connectManually")
|
||||||
|
/// Connect to Jellyfin
|
||||||
|
internal static let connectToJellyfin = L10n.tr("Localizable", "connectToJellyfin")
|
||||||
|
/// Connect to Server
|
||||||
|
internal static let connectToServer = L10n.tr("Localizable", "connectToServer")
|
||||||
|
/// Continue Watching
|
||||||
|
internal static let continueWatching = L10n.tr("Localizable", "continueWatching")
|
||||||
|
/// Dark
|
||||||
|
internal static let dark = L10n.tr("Localizable", "dark")
|
||||||
|
/// DIRECTOR
|
||||||
|
internal static let director = L10n.tr("Localizable", "director")
|
||||||
|
/// Discovered Servers
|
||||||
|
internal static let discoveredServers = L10n.tr("Localizable", "discoveredServers")
|
||||||
|
/// Display order
|
||||||
|
internal static let displayOrder = L10n.tr("Localizable", "displayOrder")
|
||||||
|
/// Empty Next Up
|
||||||
|
internal static let emptyNextUp = L10n.tr("Localizable", "emptyNextUp")
|
||||||
|
/// Episodes
|
||||||
|
internal static let episodes = L10n.tr("Localizable", "episodes")
|
||||||
|
/// Error
|
||||||
|
internal static let error = L10n.tr("Localizable", "error")
|
||||||
|
/// Filter Results
|
||||||
|
internal static let filterResults = L10n.tr("Localizable", "filterResults")
|
||||||
|
/// Filters
|
||||||
|
internal static let filters = L10n.tr("Localizable", "filters")
|
||||||
|
/// Genres
|
||||||
|
internal static let genres = L10n.tr("Localizable", "genres")
|
||||||
|
/// Home
|
||||||
|
internal static let home = L10n.tr("Localizable", "home")
|
||||||
|
/// Latest %@
|
||||||
|
internal static func latestWithString(_ p1: Any) -> String {
|
||||||
|
return L10n.tr("Localizable", "latestWithString", String(describing: p1))
|
||||||
|
}
|
||||||
|
/// Library
|
||||||
|
internal static let library = L10n.tr("Localizable", "library")
|
||||||
|
/// Light
|
||||||
|
internal static let light = L10n.tr("Localizable", "light")
|
||||||
|
/// Loading
|
||||||
|
internal static let loading = L10n.tr("Localizable", "loading")
|
||||||
|
/// Local Servers
|
||||||
|
internal static let localServers = L10n.tr("Localizable", "localServers")
|
||||||
|
/// Login
|
||||||
|
internal static let login = L10n.tr("Localizable", "login")
|
||||||
|
/// Login to %@
|
||||||
|
internal static func loginToWithString(_ p1: Any) -> String {
|
||||||
|
return L10n.tr("Localizable", "loginToWithString", String(describing: p1))
|
||||||
|
}
|
||||||
|
/// More Like This
|
||||||
|
internal static let moreLikeThis = L10n.tr("Localizable", "moreLikeThis")
|
||||||
|
/// Next Up
|
||||||
|
internal static let nextUp = L10n.tr("Localizable", "nextUp")
|
||||||
|
/// No Cast devices found..
|
||||||
|
internal static let noCastdevicesfound = L10n.tr("Localizable", "noCastdevicesfound")
|
||||||
|
/// No results.
|
||||||
|
internal static let noResults = L10n.tr("Localizable", "noResults")
|
||||||
|
/// Type: %@ not implemented yet :(
|
||||||
|
internal static func notImplementedYetWithType(_ p1: Any) -> String {
|
||||||
|
return L10n.tr("Localizable", "notImplementedYetWithType", String(describing: p1))
|
||||||
|
}
|
||||||
|
/// Ok
|
||||||
|
internal static let ok = L10n.tr("Localizable", "ok")
|
||||||
|
/// Other User
|
||||||
|
internal static let otherUser = L10n.tr("Localizable", "otherUser")
|
||||||
|
/// Page %1$@ of %2$@
|
||||||
|
internal static func pageOfWithNumbers(_ p1: Any, _ p2: Any) -> String {
|
||||||
|
return L10n.tr("Localizable", "pageOfWithNumbers", String(describing: p1), String(describing: p2))
|
||||||
|
}
|
||||||
|
/// Password
|
||||||
|
internal static let password = L10n.tr("Localizable", "password")
|
||||||
|
/// Play
|
||||||
|
internal static let play = L10n.tr("Localizable", "play")
|
||||||
|
/// Playback settings
|
||||||
|
internal static let playbackSettings = L10n.tr("Localizable", "playbackSettings")
|
||||||
|
/// Playback Speed
|
||||||
|
internal static let playbackSpeed = L10n.tr("Localizable", "playbackSpeed")
|
||||||
|
/// Play Next
|
||||||
|
internal static let playNext = L10n.tr("Localizable", "playNext")
|
||||||
|
/// Reset
|
||||||
|
internal static let reset = L10n.tr("Localizable", "reset")
|
||||||
|
/// Search...
|
||||||
|
internal static let search = L10n.tr("Localizable", "search")
|
||||||
|
/// S%1$@:E%2$@
|
||||||
|
internal static func seasonAndEpisode(_ p1: Any, _ p2: Any) -> String {
|
||||||
|
return L10n.tr("Localizable", "seasonAndEpisode", String(describing: p1), String(describing: p2))
|
||||||
|
}
|
||||||
|
/// Seasons
|
||||||
|
internal static let seasons = L10n.tr("Localizable", "seasons")
|
||||||
|
/// See All
|
||||||
|
internal static let seeAll = L10n.tr("Localizable", "seeAll")
|
||||||
|
/// Select Cast Destination
|
||||||
|
internal static let selectCastDestination = L10n.tr("Localizable", "selectCastDestination")
|
||||||
|
/// Server Information
|
||||||
|
internal static let serverInformation = L10n.tr("Localizable", "serverInformation")
|
||||||
|
/// Server URL
|
||||||
|
internal static let serverURL = L10n.tr("Localizable", "serverURL")
|
||||||
|
/// Signed in as %@
|
||||||
|
internal static func signedInAsWithString(_ p1: Any) -> String {
|
||||||
|
return L10n.tr("Localizable", "signedInAsWithString", String(describing: p1))
|
||||||
|
}
|
||||||
|
/// Sort by
|
||||||
|
internal static let sortBy = L10n.tr("Localizable", "sortBy")
|
||||||
|
/// STUDIO
|
||||||
|
internal static let studio = L10n.tr("Localizable", "studio")
|
||||||
|
/// Studios
|
||||||
|
internal static let studios = L10n.tr("Localizable", "studios")
|
||||||
|
/// Suggestions
|
||||||
|
internal static let suggestions = L10n.tr("Localizable", "suggestions")
|
||||||
|
/// Switch user
|
||||||
|
internal static let switchUser = L10n.tr("Localizable", "switchUser")
|
||||||
|
/// System
|
||||||
|
internal static let system = L10n.tr("Localizable", "system")
|
||||||
|
/// Tags
|
||||||
|
internal static let tags = L10n.tr("Localizable", "tags")
|
||||||
|
/// Try again
|
||||||
|
internal static let tryAgain = L10n.tr("Localizable", "tryAgain")
|
||||||
|
/// Username
|
||||||
|
internal static let username = L10n.tr("Localizable", "username")
|
||||||
|
/// Who's watching?
|
||||||
|
internal static let whosWatching = L10n.tr("Localizable", "WhosWatching")
|
||||||
|
/// WIP
|
||||||
|
internal static let wip = L10n.tr("Localizable", "wip")
|
||||||
|
/// Your Favorites
|
||||||
|
internal static let yourFavorites = L10n.tr("Localizable", "yourFavorites")
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
|
||||||
|
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
extension L10n {
|
||||||
|
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||||
|
let format = BundleToken.bundle.localizedString(forKey: key, value: nil, table: table)
|
||||||
|
return String(format: format, locale: Locale.current, arguments: args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
|
@ -18,11 +18,11 @@ enum AppAppearance: String, CaseIterable, Defaults.Serializable {
|
||||||
var localizedName: String {
|
var localizedName: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .system:
|
case .system:
|
||||||
return R.string.localizable.system()
|
return L10n.system
|
||||||
case .dark:
|
case .dark:
|
||||||
return R.string.localizable.dark()
|
return L10n.dark
|
||||||
case .light:
|
case .light:
|
||||||
return R.string.localizable.light()
|
return L10n.light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ enum ItemType: String {
|
||||||
var localized: String {
|
var localized: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .episode:
|
case .episode:
|
||||||
return R.string.localizable.episodes()
|
return L10n.episodes
|
||||||
case .movie:
|
case .movie:
|
||||||
return "Movies"
|
return "Movies"
|
||||||
case .series:
|
case .series:
|
||||||
|
|
|
@ -35,7 +35,7 @@ class ItemViewModel: ViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
func playButtonText() -> String {
|
func playButtonText() -> String {
|
||||||
return item.getItemProgressString() == "" ? R.string.localizable.play() : item.getItemProgressString()
|
return item.getItemProgressString() == "" ? L10n.play : item.getItemProgressString()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getItemDisplayName() -> String {
|
func getItemDisplayName() -> String {
|
||||||
|
|
|
@ -24,8 +24,8 @@ final class SeasonItemViewModel: ItemViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func playButtonText() -> String {
|
override func playButtonText() -> String {
|
||||||
guard let playButtonItem = playButtonItem else { return R.string.localizable.play() }
|
guard let playButtonItem = playButtonItem else { return L10n.play }
|
||||||
guard let episodeLocator = playButtonItem.getEpisodeLocator() else { return R.string.localizable.play() }
|
guard let episodeLocator = playButtonItem.getEpisodeLocator() else { return L10n.play }
|
||||||
return episodeLocator
|
return episodeLocator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ final class SeriesItemViewModel: ItemViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func playButtonText() -> String {
|
override func playButtonText() -> String {
|
||||||
guard let playButtonItem = playButtonItem else { return R.string.localizable.play() }
|
guard let playButtonItem = playButtonItem else { return L10n.play }
|
||||||
guard let episodeLocator = playButtonItem.getEpisodeLocator() else { return R.string.localizable.play() }
|
guard let episodeLocator = playButtonItem.getEpisodeLocator() else { return L10n.play }
|
||||||
return episodeLocator
|
return episodeLocator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct SearchBar: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(spacing: 8) {
|
HStack(spacing: 8) {
|
||||||
TextField(R.string.localizable.search(), text: $text)
|
TextField(L10n.search, text: $text)
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.padding(.horizontal, 16)
|
.padding(.horizontal, 16)
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
|
|
|
@ -135,7 +135,7 @@ struct NextUpEntryView: View {
|
||||||
}
|
}
|
||||||
.background(Color.blue)
|
.background(Color.blue)
|
||||||
} else if entry.items.isEmpty {
|
} else if entry.items.isEmpty {
|
||||||
R.string.localizable.emptyNextUp()
|
L10n.emptyNextUp.text
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.bold()
|
.bold()
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
@ -214,7 +214,7 @@ extension NextUpEntryView {
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
Text("\(item.0.name ?? "") · \(R.string.localizable.seasonAndEpisode(String(item.0.parentIndexNumber ?? 0), String(item.0.indexNumber ?? 0)))")
|
Text("\(item.0.name ?? "") · \(L10n.seasonAndEpisode(String(item.0.parentIndexNumber ?? 0), String(item.0.indexNumber ?? 0)))")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
|
@ -242,7 +242,7 @@ extension NextUpEntryView {
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
|
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
Text("\(item.0.name ?? "") · \(R.string.localizable.seasonAndEpisode(String(item.0.parentIndexNumber ?? 0), String(item.0.indexNumber ?? 0)))")
|
Text("\(item.0.name ?? "") · \(L10n.seasonAndEpisode(String(item.0.parentIndexNumber ?? 0), String(item.0.indexNumber ?? 0)))")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
|
@ -304,7 +304,7 @@ extension NextUpEntryView {
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
|
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
|
||||||
Text("\(firstItem.0.name ?? "") · \(R.string.localizable.seasonAndEpisode(String(firstItem.0.parentIndexNumber ?? 0), String(firstItem.0.indexNumber ?? 0)))")
|
Text("\(firstItem.0.name ?? "") · \(L10n.seasonAndEpisode(String(firstItem.0.parentIndexNumber ?? 0), String(firstItem.0.indexNumber ?? 0)))")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
@ -346,7 +346,7 @@ struct NextUpWidget: Widget {
|
||||||
provider: NextUpWidgetProvider()) { entry in
|
provider: NextUpWidgetProvider()) { entry in
|
||||||
NextUpEntryView(entry: entry)
|
NextUpEntryView(entry: entry)
|
||||||
}
|
}
|
||||||
.configurationDisplayName(R.string.localizable.nextUp())
|
.configurationDisplayName(L10n.nextUp)
|
||||||
.description("Keep watching where you left off or see what's up next.")
|
.description("Keep watching where you left off or see what's up next.")
|
||||||
.supportedFamilies([.systemSmall, .systemMedium, .systemLarge])
|
.supportedFamilies([.systemSmall, .systemMedium, .systemLarge])
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>BuildMachineOSBuild</key>
|
||||||
|
<string></string>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>SwiftGen_SwiftGenCLI</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>SwiftGen.SwiftGenCLI.resources</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>SwiftGen_SwiftGenCLI</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>BNDL</string>
|
||||||
|
<key>CFBundleSupportedPlatforms</key>
|
||||||
|
<array>
|
||||||
|
<string>MacOSX</string>
|
||||||
|
</array>
|
||||||
|
<key>DTCompiler</key>
|
||||||
|
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||||
|
<key>DTPlatformBuild</key>
|
||||||
|
<string>13A233</string>
|
||||||
|
<key>DTPlatformName</key>
|
||||||
|
<string>macosx</string>
|
||||||
|
<key>DTPlatformVersion</key>
|
||||||
|
<string>11.3</string>
|
||||||
|
<key>DTSDKBuild</key>
|
||||||
|
<string>20E214</string>
|
||||||
|
<key>DTSDKName</key>
|
||||||
|
<string>macosx11.3</string>
|
||||||
|
<key>DTXcode</key>
|
||||||
|
<string>1300</string>
|
||||||
|
<key>DTXcodeBuild</key>
|
||||||
|
<string>13A233</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>10.11</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,43 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if palettes %}
|
||||||
|
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
#if os(macOS)
|
||||||
|
import AppKit
|
||||||
|
{% if enumName != 'NSColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
import UIKit
|
||||||
|
{% if enumName != 'UIColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - Colors
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{{accessModifier}} extension {{enumName}} {
|
||||||
|
{% macro h2f hex %}{{hex|hexToInt|int255toFloat}}{% endmacro %}
|
||||||
|
{% macro enumBlock colors accessPrefix %}
|
||||||
|
{% for color in colors %}
|
||||||
|
/// 0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}} (r: {{color.red|hexToInt}}, g: {{color.green|hexToInt}}, b: {{color.blue|hexToInt}}, a: {{color.alpha|hexToInt}})
|
||||||
|
{{accessPrefix}}static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = #colorLiteral(red: {% call h2f color.red %}, green: {% call h2f color.green %}, blue: {% call h2f color.blue %}, alpha: {% call h2f color.alpha %})
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% if palettes.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% set accessPrefix %}{{accessModifier}} {% endset %}
|
||||||
|
{% for palette in palettes %}
|
||||||
|
enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call enumBlock palette.colors accessPrefix %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call enumBlock palettes.first.colors "" %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
||||||
|
{% else %}
|
||||||
|
// No color found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,43 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if palettes %}
|
||||||
|
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
#if os(macOS)
|
||||||
|
import AppKit
|
||||||
|
{% if enumName != 'NSColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
import UIKit
|
||||||
|
{% if enumName != 'UIColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - Colors
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{{accessModifier}} extension {{enumName}} {
|
||||||
|
{% macro h2f hex %}{{hex|hexToInt|int255toFloat}}{% endmacro %}
|
||||||
|
{% macro enumBlock colors accessPrefix %}
|
||||||
|
{% for color in colors %}
|
||||||
|
/// 0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}} (r: {{color.red|hexToInt}}, g: {{color.green|hexToInt}}, b: {{color.blue|hexToInt}}, a: {{color.alpha|hexToInt}})
|
||||||
|
{{accessPrefix}}static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = #colorLiteral(red: {% call h2f color.red %}, green: {% call h2f color.green %}, blue: {% call h2f color.blue %}, alpha: {% call h2f color.alpha %})
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% if palettes.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% set accessPrefix %}{{accessModifier}} {% endset %}
|
||||||
|
{% for palette in palettes %}
|
||||||
|
enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call enumBlock palette.colors accessPrefix %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call enumBlock palettes.first.colors "" %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
||||||
|
{% else %}
|
||||||
|
// No color found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,84 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if palettes %}
|
||||||
|
{% set colorAlias %}{{param.colorAliasName|default:"Color"}}{% endset %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
#if os(macOS)
|
||||||
|
import AppKit.NSColor
|
||||||
|
{{accessModifier}} typealias {{colorAlias}} = NSColor
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
import UIKit.UIColor
|
||||||
|
{{accessModifier}} typealias {{colorAlias}} = UIColor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Colors
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
|
||||||
|
{{accessModifier}} struct {{enumName}} {
|
||||||
|
{{accessModifier}} let rgbaValue: UInt32
|
||||||
|
{{accessModifier}} var color: {{colorAlias}} { return {{colorAlias}}(named: self) }
|
||||||
|
|
||||||
|
{% macro rgbaValue color %}0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}}{% endmacro %}
|
||||||
|
{% macro enumBlock colors %}
|
||||||
|
{% for color in colors %}
|
||||||
|
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#{{color.red}}{{color.green}}{{color.blue}}"></span>
|
||||||
|
/// Alpha: {{color.alpha|hexToInt|int255toFloat|percent}} <br/> (0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}})
|
||||||
|
{{accessModifier}} static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}(rgbaValue: {% call rgbaValue color %})
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% if palettes.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for palette in palettes %}
|
||||||
|
{{accessModifier}} enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call enumBlock palette.colors %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call enumBlock palettes.first.colors %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
internal extension {{colorAlias}} {
|
||||||
|
convenience init(rgbaValue: UInt32) {
|
||||||
|
let components = RGBAComponents(rgbaValue: rgbaValue).normalized
|
||||||
|
self.init(red: components[0], green: components[1], blue: components[2], alpha: components[3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct RGBAComponents {
|
||||||
|
let rgbaValue: UInt32
|
||||||
|
|
||||||
|
private var shifts: [UInt32] {
|
||||||
|
[
|
||||||
|
rgbaValue >> 24, // red
|
||||||
|
rgbaValue >> 16, // green
|
||||||
|
rgbaValue >> 8, // blue
|
||||||
|
rgbaValue // alpha
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
private var components: [CGFloat] {
|
||||||
|
shifts.map {
|
||||||
|
CGFloat($0 & 0xff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalized: [CGFloat] {
|
||||||
|
components.map { $0 / 255.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension {{colorAlias}} {
|
||||||
|
convenience init(named color: {{enumName}}) {
|
||||||
|
self.init(rgbaValue: color.rgbaValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
|
// No color found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,84 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if palettes %}
|
||||||
|
{% set colorAlias %}{{param.colorAliasName|default:"Color"}}{% endset %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
#if os(macOS)
|
||||||
|
import AppKit.NSColor
|
||||||
|
{{accessModifier}} typealias {{colorAlias}} = NSColor
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
import UIKit.UIColor
|
||||||
|
{{accessModifier}} typealias {{colorAlias}} = UIColor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Colors
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
|
||||||
|
{{accessModifier}} struct {{enumName}} {
|
||||||
|
{{accessModifier}} let rgbaValue: UInt32
|
||||||
|
{{accessModifier}} var color: {{colorAlias}} { return {{colorAlias}}(named: self) }
|
||||||
|
|
||||||
|
{% macro rgbaValue color %}0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}}{% endmacro %}
|
||||||
|
{% macro enumBlock colors %}
|
||||||
|
{% for color in colors %}
|
||||||
|
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#{{color.red}}{{color.green}}{{color.blue}}"></span>
|
||||||
|
/// Alpha: {{color.alpha|hexToInt|int255toFloat|percent}} <br/> (0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}})
|
||||||
|
{{accessModifier}} static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}(rgbaValue: {% call rgbaValue color %})
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% if palettes.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for palette in palettes %}
|
||||||
|
{{accessModifier}} enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call enumBlock palette.colors %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call enumBlock palettes.first.colors %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
internal extension {{colorAlias}} {
|
||||||
|
convenience init(rgbaValue: UInt32) {
|
||||||
|
let components = RGBAComponents(rgbaValue: rgbaValue).normalized
|
||||||
|
self.init(red: components[0], green: components[1], blue: components[2], alpha: components[3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct RGBAComponents {
|
||||||
|
let rgbaValue: UInt32
|
||||||
|
|
||||||
|
private var shifts: [UInt32] {
|
||||||
|
[
|
||||||
|
rgbaValue >> 24, // red
|
||||||
|
rgbaValue >> 16, // green
|
||||||
|
rgbaValue >> 8, // blue
|
||||||
|
rgbaValue // alpha
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
private var components: [CGFloat] {
|
||||||
|
shifts.map {
|
||||||
|
CGFloat($0 & 0xff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalized: [CGFloat] {
|
||||||
|
components.map { $0 / 255.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension {{colorAlias}} {
|
||||||
|
convenience init(named color: {{enumName}}) {
|
||||||
|
self.init(rgbaValue: color.rgbaValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
|
// No color found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,211 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command implicit_return
|
||||||
|
// swiftlint:disable sorted_imports
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
{% for import in param.extraImports %}
|
||||||
|
import {{ import }}
|
||||||
|
{% empty %}
|
||||||
|
{# If extraImports is a single String instead of an array, `for` considers it empty but we still have to check if there's a single String value #}
|
||||||
|
{% if param.extraImports %}import {{ param.extraImports }}{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
// swiftlint:disable attributes file_length vertical_whitespace_closing_braces
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
|
||||||
|
{% for model in models %}
|
||||||
|
{% for name, entity in model.entities %}
|
||||||
|
{% set superclass %}{{ model.entities[entity.superEntity].className|default:"NSManagedObject" }}{% endset %}
|
||||||
|
{% set entityClassName %}{{ entity.className|default:"NSManagedObject" }}{% endset %}
|
||||||
|
// MARK: - {{ entity.name }}
|
||||||
|
|
||||||
|
{% if not entity.shouldGenerateCode %}
|
||||||
|
// Note: '{{ entity.name }}' has codegen enabled for Xcode, skipping code generation.
|
||||||
|
|
||||||
|
{% elif entityClassName|contains:"." %}
|
||||||
|
// Warning: '{{ entityClassName }}' cannot be a valid type name, skipping code generation.
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{% if param.generateObjcName %}
|
||||||
|
@objc({{ entityClassName }})
|
||||||
|
{% endif %}
|
||||||
|
{{ accessModifier }} class {{ entityClassName }}: {{ superclass }} {
|
||||||
|
{% set override %}{% if superclass != "NSManagedObject" %}override {% endif %}{% endset %}
|
||||||
|
{{ override }}{{ accessModifier }} class var entityName: String {
|
||||||
|
return "{{ entity.name }}"
|
||||||
|
}
|
||||||
|
|
||||||
|
{{ override }}{{ accessModifier }} class func entity(in managedObjectContext: NSManagedObjectContext) -> NSEntityDescription? {
|
||||||
|
return NSEntityDescription.entity(forEntityName: entityName, in: managedObjectContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, deprecated, renamed: "makeFetchRequest", message: "To avoid collisions with the less concrete method in `NSManagedObject`, please use `makeFetchRequest()` instead.")
|
||||||
|
@nonobjc {{ accessModifier }} class func fetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
|
||||||
|
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
|
||||||
|
}
|
||||||
|
|
||||||
|
@nonobjc {{ accessModifier }} class func makeFetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
|
||||||
|
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:disable discouraged_optional_boolean discouraged_optional_collection
|
||||||
|
{% for attribute in entity.attributes %}
|
||||||
|
{% if attribute.userInfo.RawType %}
|
||||||
|
{% set rawType attribute.userInfo.RawType %}
|
||||||
|
{% set unwrapOptional attribute.userInfo.unwrapOptional %}
|
||||||
|
{{ accessModifier }} var {{ attribute.name }}: {{ rawType }}{% if not unwrapOptional %}?{% endif %} {
|
||||||
|
get {
|
||||||
|
let key = "{{ attribute.name }}"
|
||||||
|
willAccessValue(forKey: key)
|
||||||
|
defer { didAccessValue(forKey: key) }
|
||||||
|
|
||||||
|
{% if unwrapOptional %}
|
||||||
|
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue,
|
||||||
|
let result = {{ rawType }}(rawValue: value) else {
|
||||||
|
fatalError("Could not convert value for key '\(key)' to type '{{ rawType }}'")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
{% else %}
|
||||||
|
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return {{ rawType }}(rawValue: value)
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
let key = "{{ attribute.name }}"
|
||||||
|
willChangeValue(forKey: key)
|
||||||
|
defer { didChangeValue(forKey: key) }
|
||||||
|
|
||||||
|
setPrimitiveValue(newValue{% if not unwrapOptional %}?{% endif %}.rawValue, forKey: key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% elif attribute.usesScalarValueType and attribute.isOptional %}
|
||||||
|
{{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}? {
|
||||||
|
get {
|
||||||
|
let key = "{{ attribute.name }}"
|
||||||
|
willAccessValue(forKey: key)
|
||||||
|
defer { didAccessValue(forKey: key) }
|
||||||
|
|
||||||
|
return primitiveValue(forKey: key) as? {{ attribute.typeName }}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
let key = "{{ attribute.name }}"
|
||||||
|
willChangeValue(forKey: key)
|
||||||
|
defer { didChangeValue(forKey: key) }
|
||||||
|
|
||||||
|
setPrimitiveValue(newValue, forKey: key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
|
@NSManaged {{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}{% if attribute.isOptional %}?{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for relationship in entity.relationships %}
|
||||||
|
{% if relationship.isToMany %}
|
||||||
|
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}>{% endif %}{% if relationship.isOptional %}?{% endif %}
|
||||||
|
{% else %}
|
||||||
|
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% if relationship.isOptional %}?{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for fetchedProperty in entity.fetchedProperties %}
|
||||||
|
@NSManaged {{ accessModifier }} var {{ fetchedProperty.name }}: [{{ fetchedProperty.fetchRequest.entity }}]
|
||||||
|
{% endfor %}
|
||||||
|
// swiftlint:enable discouraged_optional_boolean discouraged_optional_collection
|
||||||
|
}
|
||||||
|
|
||||||
|
{% for relationship in entity.relationships where relationship.isToMany %}
|
||||||
|
{% set destinationEntityClassName %}{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% endset %}
|
||||||
|
{% set collectionClassName %}{% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ destinationEntityClassName }}>{% endif %}{% endset %}
|
||||||
|
{% set relationshipName %}{{ relationship.name | upperFirstLetter }}{% endset %}
|
||||||
|
// MARK: Relationship {{ relationshipName }}
|
||||||
|
|
||||||
|
extension {{ entityClassName }} {
|
||||||
|
{% if relationship.isOrdered %}
|
||||||
|
@objc(insertObject:in{{ relationshipName }}AtIndex:)
|
||||||
|
@NSManaged public func insertInto{{ relationshipName }}(_ value: {{ destinationEntityClassName }}, at idx: Int)
|
||||||
|
|
||||||
|
@objc(removeObjectFrom{{ relationshipName }}AtIndex:)
|
||||||
|
@NSManaged public func removeFrom{{ relationshipName }}(at idx: Int)
|
||||||
|
|
||||||
|
@objc(insert{{ relationshipName }}:atIndexes:)
|
||||||
|
@NSManaged public func insertInto{{ relationshipName }}(_ values: [{{ destinationEntityClassName }}], at indexes: NSIndexSet)
|
||||||
|
|
||||||
|
@objc(remove{{ relationshipName }}AtIndexes:)
|
||||||
|
@NSManaged public func removeFrom{{ relationshipName }}(at indexes: NSIndexSet)
|
||||||
|
|
||||||
|
@objc(replaceObjectIn{{ relationshipName }}AtIndex:withObject:)
|
||||||
|
@NSManaged public func replace{{ relationshipName }}(at idx: Int, with value: {{ destinationEntityClassName }})
|
||||||
|
|
||||||
|
@objc(replace{{ relationshipName }}AtIndexes:with{{ relationshipName }}:)
|
||||||
|
@NSManaged public func replace{{ relationshipName }}(at indexes: NSIndexSet, with values: [{{ destinationEntityClassName }}])
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
@objc(add{{ relationshipName }}Object:)
|
||||||
|
@NSManaged public func addTo{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
|
||||||
|
|
||||||
|
@objc(remove{{ relationshipName }}Object:)
|
||||||
|
@NSManaged public func removeFrom{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
|
||||||
|
|
||||||
|
@objc(add{{ relationshipName }}:)
|
||||||
|
@NSManaged public func addTo{{ relationshipName }}(_ values: {{ collectionClassName }})
|
||||||
|
|
||||||
|
@objc(remove{{ relationshipName }}:)
|
||||||
|
@NSManaged public func removeFrom{{ relationshipName }}(_ values: {{ collectionClassName }})
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% if model.fetchRequests[entity.name].count > 0 %}
|
||||||
|
// MARK: Fetch Requests
|
||||||
|
|
||||||
|
extension {{ entityClassName }} {
|
||||||
|
{% for fetchRequest in model.fetchRequests[entity.name] %}
|
||||||
|
{% set resultTypeName %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if fetchRequest.resultType == "Object" %}
|
||||||
|
{{ entityClassName }}
|
||||||
|
{% elif fetchRequest.resultType == "Object ID" %}
|
||||||
|
NSManagedObjectID
|
||||||
|
{% elif fetchRequest.resultType == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endset %}
|
||||||
|
class func fetch{{ fetchRequest.name | upperFirstLetter }}({% filter removeNewlines:"leading" %}
|
||||||
|
managedObjectContext: NSManagedObjectContext
|
||||||
|
{% for variableName, variableType in fetchRequest.substitutionVariables %}
|
||||||
|
, {{ variableName | lowerFirstWord }}: {{ variableType }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}) throws -> [{{ resultTypeName }}] {
|
||||||
|
guard let persistentStoreCoordinator = managedObjectContext.persistentStoreCoordinator else {
|
||||||
|
fatalError("Managed object context has no persistent store coordinator for getting fetch request templates")
|
||||||
|
}
|
||||||
|
let model = persistentStoreCoordinator.managedObjectModel
|
||||||
|
let substitutionVariables: [String: Any] = [
|
||||||
|
{% for variableName, variableType in fetchRequest.substitutionVariables %}
|
||||||
|
"{{ variableName }}": {{ variableName | lowerFirstWord }}{{ "," if not forloop.last }}
|
||||||
|
{% empty %}
|
||||||
|
:
|
||||||
|
{% endfor %}
|
||||||
|
]
|
||||||
|
|
||||||
|
guard let fetchRequest = model.fetchRequestFromTemplate(withName: "{{ fetchRequest.name }}", substitutionVariables: substitutionVariables) else {
|
||||||
|
fatalError("No fetch request template named '{{ fetchRequest.name }}' found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let result = try managedObjectContext.fetch(fetchRequest) as? [{{ resultTypeName }}] else {
|
||||||
|
fatalError("Unable to cast fetch result to correct result type.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
|
@ -0,0 +1,211 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command implicit_return
|
||||||
|
// swiftlint:disable sorted_imports
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
{% for import in param.extraImports %}
|
||||||
|
import {{ import }}
|
||||||
|
{% empty %}
|
||||||
|
{# If extraImports is a single String instead of an array, `for` considers it empty but we still have to check if there's a single String value #}
|
||||||
|
{% if param.extraImports %}import {{ param.extraImports }}{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
// swiftlint:disable attributes file_length vertical_whitespace_closing_braces
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
|
||||||
|
{% for model in models %}
|
||||||
|
{% for name, entity in model.entities %}
|
||||||
|
{% set superclass %}{{ model.entities[entity.superEntity].className|default:"NSManagedObject" }}{% endset %}
|
||||||
|
{% set entityClassName %}{{ entity.className|default:"NSManagedObject" }}{% endset %}
|
||||||
|
// MARK: - {{ entity.name }}
|
||||||
|
|
||||||
|
{% if not entity.shouldGenerateCode %}
|
||||||
|
// Note: '{{ entity.name }}' has codegen enabled for Xcode, skipping code generation.
|
||||||
|
|
||||||
|
{% elif entityClassName|contains:"." %}
|
||||||
|
// Warning: '{{ entityClassName }}' cannot be a valid type name, skipping code generation.
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{% if param.generateObjcName %}
|
||||||
|
@objc({{ entityClassName }})
|
||||||
|
{% endif %}
|
||||||
|
{{ accessModifier }} class {{ entityClassName }}: {{ superclass }} {
|
||||||
|
{% set override %}{% if superclass != "NSManagedObject" %}override {% endif %}{% endset %}
|
||||||
|
{{ override }}{{ accessModifier }} class var entityName: String {
|
||||||
|
return "{{ entity.name }}"
|
||||||
|
}
|
||||||
|
|
||||||
|
{{ override }}{{ accessModifier }} class func entity(in managedObjectContext: NSManagedObjectContext) -> NSEntityDescription? {
|
||||||
|
return NSEntityDescription.entity(forEntityName: entityName, in: managedObjectContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, deprecated, renamed: "makeFetchRequest", message: "To avoid collisions with the less concrete method in `NSManagedObject`, please use `makeFetchRequest()` instead.")
|
||||||
|
@nonobjc {{ accessModifier }} class func fetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
|
||||||
|
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
|
||||||
|
}
|
||||||
|
|
||||||
|
@nonobjc {{ accessModifier }} class func makeFetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
|
||||||
|
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:disable discouraged_optional_boolean discouraged_optional_collection
|
||||||
|
{% for attribute in entity.attributes %}
|
||||||
|
{% if attribute.userInfo.RawType %}
|
||||||
|
{% set rawType attribute.userInfo.RawType %}
|
||||||
|
{% set unwrapOptional attribute.userInfo.unwrapOptional %}
|
||||||
|
{{ accessModifier }} var {{ attribute.name }}: {{ rawType }}{% if not unwrapOptional %}?{% endif %} {
|
||||||
|
get {
|
||||||
|
let key = "{{ attribute.name }}"
|
||||||
|
willAccessValue(forKey: key)
|
||||||
|
defer { didAccessValue(forKey: key) }
|
||||||
|
|
||||||
|
{% if unwrapOptional %}
|
||||||
|
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue,
|
||||||
|
let result = {{ rawType }}(rawValue: value) else {
|
||||||
|
fatalError("Could not convert value for key '\(key)' to type '{{ rawType }}'")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
{% else %}
|
||||||
|
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return {{ rawType }}(rawValue: value)
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
let key = "{{ attribute.name }}"
|
||||||
|
willChangeValue(forKey: key)
|
||||||
|
defer { didChangeValue(forKey: key) }
|
||||||
|
|
||||||
|
setPrimitiveValue(newValue{% if not unwrapOptional %}?{% endif %}.rawValue, forKey: key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% elif attribute.usesScalarValueType and attribute.isOptional %}
|
||||||
|
{{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}? {
|
||||||
|
get {
|
||||||
|
let key = "{{ attribute.name }}"
|
||||||
|
willAccessValue(forKey: key)
|
||||||
|
defer { didAccessValue(forKey: key) }
|
||||||
|
|
||||||
|
return primitiveValue(forKey: key) as? {{ attribute.typeName }}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
let key = "{{ attribute.name }}"
|
||||||
|
willChangeValue(forKey: key)
|
||||||
|
defer { didChangeValue(forKey: key) }
|
||||||
|
|
||||||
|
setPrimitiveValue(newValue, forKey: key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
|
@NSManaged {{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}{% if attribute.isOptional %}?{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for relationship in entity.relationships %}
|
||||||
|
{% if relationship.isToMany %}
|
||||||
|
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}>{% endif %}{% if relationship.isOptional %}?{% endif %}
|
||||||
|
{% else %}
|
||||||
|
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% if relationship.isOptional %}?{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for fetchedProperty in entity.fetchedProperties %}
|
||||||
|
@NSManaged {{ accessModifier }} var {{ fetchedProperty.name }}: [{{ fetchedProperty.fetchRequest.entity }}]
|
||||||
|
{% endfor %}
|
||||||
|
// swiftlint:enable discouraged_optional_boolean discouraged_optional_collection
|
||||||
|
}
|
||||||
|
|
||||||
|
{% for relationship in entity.relationships where relationship.isToMany %}
|
||||||
|
{% set destinationEntityClassName %}{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% endset %}
|
||||||
|
{% set collectionClassName %}{% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ destinationEntityClassName }}>{% endif %}{% endset %}
|
||||||
|
{% set relationshipName %}{{ relationship.name | upperFirstLetter }}{% endset %}
|
||||||
|
// MARK: Relationship {{ relationshipName }}
|
||||||
|
|
||||||
|
extension {{ entityClassName }} {
|
||||||
|
{% if relationship.isOrdered %}
|
||||||
|
@objc(insertObject:in{{ relationshipName }}AtIndex:)
|
||||||
|
@NSManaged public func insertInto{{ relationshipName }}(_ value: {{ destinationEntityClassName }}, at idx: Int)
|
||||||
|
|
||||||
|
@objc(removeObjectFrom{{ relationshipName }}AtIndex:)
|
||||||
|
@NSManaged public func removeFrom{{ relationshipName }}(at idx: Int)
|
||||||
|
|
||||||
|
@objc(insert{{ relationshipName }}:atIndexes:)
|
||||||
|
@NSManaged public func insertInto{{ relationshipName }}(_ values: [{{ destinationEntityClassName }}], at indexes: NSIndexSet)
|
||||||
|
|
||||||
|
@objc(remove{{ relationshipName }}AtIndexes:)
|
||||||
|
@NSManaged public func removeFrom{{ relationshipName }}(at indexes: NSIndexSet)
|
||||||
|
|
||||||
|
@objc(replaceObjectIn{{ relationshipName }}AtIndex:withObject:)
|
||||||
|
@NSManaged public func replace{{ relationshipName }}(at idx: Int, with value: {{ destinationEntityClassName }})
|
||||||
|
|
||||||
|
@objc(replace{{ relationshipName }}AtIndexes:with{{ relationshipName }}:)
|
||||||
|
@NSManaged public func replace{{ relationshipName }}(at indexes: NSIndexSet, with values: [{{ destinationEntityClassName }}])
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
@objc(add{{ relationshipName }}Object:)
|
||||||
|
@NSManaged public func addTo{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
|
||||||
|
|
||||||
|
@objc(remove{{ relationshipName }}Object:)
|
||||||
|
@NSManaged public func removeFrom{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
|
||||||
|
|
||||||
|
@objc(add{{ relationshipName }}:)
|
||||||
|
@NSManaged public func addTo{{ relationshipName }}(_ values: {{ collectionClassName }})
|
||||||
|
|
||||||
|
@objc(remove{{ relationshipName }}:)
|
||||||
|
@NSManaged public func removeFrom{{ relationshipName }}(_ values: {{ collectionClassName }})
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% if model.fetchRequests[entity.name].count > 0 %}
|
||||||
|
// MARK: Fetch Requests
|
||||||
|
|
||||||
|
extension {{ entityClassName }} {
|
||||||
|
{% for fetchRequest in model.fetchRequests[entity.name] %}
|
||||||
|
{% set resultTypeName %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if fetchRequest.resultType == "Object" %}
|
||||||
|
{{ entityClassName }}
|
||||||
|
{% elif fetchRequest.resultType == "Object ID" %}
|
||||||
|
NSManagedObjectID
|
||||||
|
{% elif fetchRequest.resultType == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endset %}
|
||||||
|
class func fetch{{ fetchRequest.name | upperFirstLetter }}({% filter removeNewlines:"leading" %}
|
||||||
|
managedObjectContext: NSManagedObjectContext
|
||||||
|
{% for variableName, variableType in fetchRequest.substitutionVariables %}
|
||||||
|
, {{ variableName | lowerFirstWord }}: {{ variableType }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}) throws -> [{{ resultTypeName }}] {
|
||||||
|
guard let persistentStoreCoordinator = managedObjectContext.persistentStoreCoordinator else {
|
||||||
|
fatalError("Managed object context has no persistent store coordinator for getting fetch request templates")
|
||||||
|
}
|
||||||
|
let model = persistentStoreCoordinator.managedObjectModel
|
||||||
|
let substitutionVariables: [String: Any] = [
|
||||||
|
{% for variableName, variableType in fetchRequest.substitutionVariables %}
|
||||||
|
"{{ variableName }}": {{ variableName | lowerFirstWord }}{{ "," if not forloop.last }}
|
||||||
|
{% empty %}
|
||||||
|
:
|
||||||
|
{% endfor %}
|
||||||
|
]
|
||||||
|
|
||||||
|
guard let fetchRequest = model.fetchRequestFromTemplate(withName: "{{ fetchRequest.name }}", substitutionVariables: substitutionVariables) else {
|
||||||
|
fatalError("No fetch request template named '{{ fetchRequest.name }}' found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let result = try managedObjectContext.fetch(fetchRequest) as? [{{ resultTypeName }}] else {
|
||||||
|
fatalError("Unable to cast fetch result to correct result type.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
|
@ -0,0 +1,103 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if groups.count > 0 %}
|
||||||
|
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
|
||||||
|
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Files
|
||||||
|
|
||||||
|
{% macro groupBlock group %}
|
||||||
|
{% for file in group.files %}
|
||||||
|
{% call fileBlock file %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for dir in group.directories %}
|
||||||
|
{% call dirBlock dir %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
|
||||||
|
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
|
||||||
|
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro dirBlock directory %}
|
||||||
|
{% for file in directory.files %}
|
||||||
|
{% call fileBlock file %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for dir in directory.directories %}
|
||||||
|
{% call dirBlock dir %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
// swiftlint:disable explicit_type_interface identifier_name
|
||||||
|
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
{{accessModifier}} enum {{enumName}} {
|
||||||
|
{% if groups.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for group in groups %}
|
||||||
|
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call groupBlock groups.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface identifier_name
|
||||||
|
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{resourceType}} {
|
||||||
|
{{accessModifier}} let name: String
|
||||||
|
{{accessModifier}} let ext: String?
|
||||||
|
{{accessModifier}} let relativePath: String
|
||||||
|
{{accessModifier}} let mimeType: String
|
||||||
|
|
||||||
|
{{accessModifier}} var url: URL {
|
||||||
|
return url(locale: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} func url(locale: Locale?) -> URL {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
let url = bundle.url(
|
||||||
|
forResource: name,
|
||||||
|
withExtension: ext,
|
||||||
|
subdirectory: relativePath,
|
||||||
|
localization: locale?.identifier
|
||||||
|
)
|
||||||
|
guard let result = url else {
|
||||||
|
let file = name + (ext.flatMap { ".\($0)" } ?? "")
|
||||||
|
fatalError("Could not locate file named \(file)")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} var path: String {
|
||||||
|
return path(locale: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} func path(locale: Locale?) -> String {
|
||||||
|
return url(locale: locale).path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type explicit_type_interface
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type explicit_type_interface
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,103 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if groups.count > 0 %}
|
||||||
|
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
|
||||||
|
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Files
|
||||||
|
|
||||||
|
{% macro groupBlock group %}
|
||||||
|
{% for file in group.files %}
|
||||||
|
{% call fileBlock file %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for dir in group.directories %}
|
||||||
|
{% call dirBlock dir %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
|
||||||
|
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
|
||||||
|
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro dirBlock directory %}
|
||||||
|
{% for file in directory.files %}
|
||||||
|
{% call fileBlock file %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for dir in directory.directories %}
|
||||||
|
{% call dirBlock dir %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
// swiftlint:disable explicit_type_interface identifier_name
|
||||||
|
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
{{accessModifier}} enum {{enumName}} {
|
||||||
|
{% if groups.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for group in groups %}
|
||||||
|
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call groupBlock groups.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface identifier_name
|
||||||
|
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{resourceType}} {
|
||||||
|
{{accessModifier}} let name: String
|
||||||
|
{{accessModifier}} let ext: String?
|
||||||
|
{{accessModifier}} let relativePath: String
|
||||||
|
{{accessModifier}} let mimeType: String
|
||||||
|
|
||||||
|
{{accessModifier}} var url: URL {
|
||||||
|
return url(locale: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} func url(locale: Locale?) -> URL {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
let url = bundle.url(
|
||||||
|
forResource: name,
|
||||||
|
withExtension: ext,
|
||||||
|
subdirectory: relativePath,
|
||||||
|
localization: locale?.identifier
|
||||||
|
)
|
||||||
|
guard let result = url else {
|
||||||
|
let file = name + (ext.flatMap { ".\($0)" } ?? "")
|
||||||
|
fatalError("Could not locate file named \(file)")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} var path: String {
|
||||||
|
return path(locale: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} func path(locale: Locale?) -> String {
|
||||||
|
return url(locale: locale).path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type explicit_type_interface
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type explicit_type_interface
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,107 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if groups.count > 0 %}
|
||||||
|
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
|
||||||
|
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Files
|
||||||
|
|
||||||
|
{% macro groupBlock group %}
|
||||||
|
{% for file in group.files %}
|
||||||
|
{% call fileBlock file %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for dir in group.directories %}
|
||||||
|
{% call dirBlock dir "" %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
|
||||||
|
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
|
||||||
|
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro dirBlock directory parent %}
|
||||||
|
{% set fullDir %}{{parent}}{{directory.name}}/{% endset %}
|
||||||
|
/// {{ fullDir }}
|
||||||
|
{{accessModifier}} enum {{directory.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% for file in directory.files %}
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for dir in directory.directories %}
|
||||||
|
{% filter indent:2 %}{% call dirBlock dir fullDir %}{% endfilter %}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endmacro %}
|
||||||
|
// swiftlint:disable explicit_type_interface identifier_name
|
||||||
|
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
{{accessModifier}} enum {{enumName}} {
|
||||||
|
{% if groups.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for group in groups %}
|
||||||
|
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call groupBlock groups.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface identifier_name
|
||||||
|
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{resourceType}} {
|
||||||
|
{{accessModifier}} let name: String
|
||||||
|
{{accessModifier}} let ext: String?
|
||||||
|
{{accessModifier}} let relativePath: String
|
||||||
|
{{accessModifier}} let mimeType: String
|
||||||
|
|
||||||
|
{{accessModifier}} var url: URL {
|
||||||
|
return url(locale: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} func url(locale: Locale?) -> URL {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
let url = bundle.url(
|
||||||
|
forResource: name,
|
||||||
|
withExtension: ext,
|
||||||
|
subdirectory: relativePath,
|
||||||
|
localization: locale?.identifier
|
||||||
|
)
|
||||||
|
guard let result = url else {
|
||||||
|
let file = name + (ext.flatMap { ".\($0)" } ?? "")
|
||||||
|
fatalError("Could not locate file named \(file)")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} var path: String {
|
||||||
|
return path(locale: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} func path(locale: Locale?) -> String {
|
||||||
|
return url(locale: locale).path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type explicit_type_interface
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type explicit_type_interface
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,107 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if groups.count > 0 %}
|
||||||
|
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
|
||||||
|
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Files
|
||||||
|
|
||||||
|
{% macro groupBlock group %}
|
||||||
|
{% for file in group.files %}
|
||||||
|
{% call fileBlock file %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for dir in group.directories %}
|
||||||
|
{% call dirBlock dir "" %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
|
||||||
|
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
|
||||||
|
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro dirBlock directory parent %}
|
||||||
|
{% set fullDir %}{{parent}}{{directory.name}}/{% endset %}
|
||||||
|
/// {{ fullDir }}
|
||||||
|
{{accessModifier}} enum {{directory.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% for file in directory.files %}
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for dir in directory.directories %}
|
||||||
|
{% filter indent:2 %}{% call dirBlock dir fullDir %}{% endfilter %}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endmacro %}
|
||||||
|
// swiftlint:disable explicit_type_interface identifier_name
|
||||||
|
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
{{accessModifier}} enum {{enumName}} {
|
||||||
|
{% if groups.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for group in groups %}
|
||||||
|
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call groupBlock groups.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface identifier_name
|
||||||
|
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{resourceType}} {
|
||||||
|
{{accessModifier}} let name: String
|
||||||
|
{{accessModifier}} let ext: String?
|
||||||
|
{{accessModifier}} let relativePath: String
|
||||||
|
{{accessModifier}} let mimeType: String
|
||||||
|
|
||||||
|
{{accessModifier}} var url: URL {
|
||||||
|
return url(locale: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} func url(locale: Locale?) -> URL {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
let url = bundle.url(
|
||||||
|
forResource: name,
|
||||||
|
withExtension: ext,
|
||||||
|
subdirectory: relativePath,
|
||||||
|
localization: locale?.identifier
|
||||||
|
)
|
||||||
|
guard let result = url else {
|
||||||
|
let file = name + (ext.flatMap { ".\($0)" } ?? "")
|
||||||
|
fatalError("Could not locate file named \(file)")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} var path: String {
|
||||||
|
return path(locale: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} func path(locale: Locale?) -> String {
|
||||||
|
return url(locale: locale).path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type explicit_type_interface
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type explicit_type_interface
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,110 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if families %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set fontType %}{{param.fontTypeName|default:"FontConvertible"}}{% endset %}
|
||||||
|
#if os(macOS)
|
||||||
|
import AppKit.NSFont
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
import UIKit.UIFont
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Deprecated typealiases
|
||||||
|
@available(*, deprecated, renamed: "{{fontType}}.Font", message: "This typealias will be removed in SwiftGen 7.0")
|
||||||
|
{{accessModifier}} typealias {{param.fontAliasName|default:"Font"}} = {{fontType}}.Font
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
// swiftlint:disable implicit_return
|
||||||
|
|
||||||
|
// MARK: - Fonts
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{% macro transformPath path %}{% filter removeNewlines %}
|
||||||
|
{% if param.preservePath %}
|
||||||
|
{{path}}
|
||||||
|
{% else %}
|
||||||
|
{{path|basename}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"FontFamily"}} {
|
||||||
|
{% for family in families %}
|
||||||
|
{{accessModifier}} enum {{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% for font in family.fonts %}
|
||||||
|
{{accessModifier}} static let {{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{fontType}}(name: "{{font.name}}", family: "{{family.name}}", path: "{% call transformPath font.path %}")
|
||||||
|
{% endfor %}
|
||||||
|
{{accessModifier}} static let all: [{{fontType}}] = [{% for font in family.fonts %}{{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{{ ", " if not forloop.last }}{% endfor %}]
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{{accessModifier}} static let allCustomFonts: [{{fontType}}] = [{% for family in families %}{{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.all{{ ", " if not forloop.last }}{% endfor %}].flatMap { $0 }
|
||||||
|
{{accessModifier}} static func registerAllCustomFonts() {
|
||||||
|
allCustomFonts.forEach { $0.register() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{fontType}} {
|
||||||
|
{{accessModifier}} let name: String
|
||||||
|
{{accessModifier}} let family: String
|
||||||
|
{{accessModifier}} let path: String
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
|
{{accessModifier}} typealias Font = NSFont
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
{{accessModifier}} typealias Font = UIFont
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{{accessModifier}} func font(size: CGFloat) -> Font! {
|
||||||
|
return Font(font: self, size: size)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} func register() {
|
||||||
|
// swiftlint:disable:next conditional_returns_on_newline
|
||||||
|
guard let url = url else { return }
|
||||||
|
CTFontManagerRegisterFontsForURL(url as CFURL, .process, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate var url: URL? {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
return {{param.lookupFunction}}(name, family, path)
|
||||||
|
{% else %}
|
||||||
|
return {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil)
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension {{fontType}}.Font {
|
||||||
|
convenience init?(font: {{fontType}}, size: CGFloat) {
|
||||||
|
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
if !UIFont.fontNames(forFamilyName: font.family).contains(font.name) {
|
||||||
|
font.register()
|
||||||
|
}
|
||||||
|
#elseif os(macOS)
|
||||||
|
if let url = font.url, CTFontManagerGetScopeForURL(url as CFURL) == .none {
|
||||||
|
font.register()
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
self.init(name: font.name, size: size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No fonts found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,113 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if families %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set fontType %}{{param.fontTypeName|default:"FontConvertible"}}{% endset %}
|
||||||
|
#if os(macOS)
|
||||||
|
import AppKit.NSFont
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
import UIKit.UIFont
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Deprecated typealiases
|
||||||
|
@available(*, deprecated, renamed: "{{fontType}}.Font", message: "This typealias will be removed in SwiftGen 7.0")
|
||||||
|
{{accessModifier}} typealias {{param.fontAliasName|default:"Font"}} = {{fontType}}.Font
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - Fonts
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{% macro transformPath path %}{% filter removeNewlines %}
|
||||||
|
{% if param.preservePath %}
|
||||||
|
{{path}}
|
||||||
|
{% else %}
|
||||||
|
{{path|basename}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"FontFamily"}} {
|
||||||
|
{% for family in families %}
|
||||||
|
{{accessModifier}} enum {{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% for font in family.fonts %}
|
||||||
|
{{accessModifier}} static let {{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{fontType}}(name: "{{font.name}}", family: "{{family.name}}", path: "{% call transformPath font.path %}")
|
||||||
|
{% endfor %}
|
||||||
|
{{accessModifier}} static let all: [{{fontType}}] = [{% for font in family.fonts %}{{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{{ ", " if not forloop.last }}{% endfor %}]
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{{accessModifier}} static let allCustomFonts: [{{fontType}}] = [{% for family in families %}{{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.all{{ ", " if not forloop.last }}{% endfor %}].flatMap { $0 }
|
||||||
|
{{accessModifier}} static func registerAllCustomFonts() {
|
||||||
|
allCustomFonts.forEach { $0.register() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{fontType}} {
|
||||||
|
{{accessModifier}} let name: String
|
||||||
|
{{accessModifier}} let family: String
|
||||||
|
{{accessModifier}} let path: String
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
|
{{accessModifier}} typealias Font = NSFont
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
{{accessModifier}} typealias Font = UIFont
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{{accessModifier}} func font(size: CGFloat) -> Font {
|
||||||
|
guard let font = Font(font: self, size: size) else {
|
||||||
|
fatalError("Unable to initialize font '\(name)' (\(family))")
|
||||||
|
}
|
||||||
|
return font
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} func register() {
|
||||||
|
// swiftlint:disable:next conditional_returns_on_newline
|
||||||
|
guard let url = url else { return }
|
||||||
|
CTFontManagerRegisterFontsForURL(url as CFURL, .process, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate var url: URL? {
|
||||||
|
// swiftlint:disable:next implicit_return
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
return {{param.lookupFunction}}(name, family, path)
|
||||||
|
{% else %}
|
||||||
|
return {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil)
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension {{fontType}}.Font {
|
||||||
|
convenience init?(font: {{fontType}}, size: CGFloat) {
|
||||||
|
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
if !UIFont.fontNames(forFamilyName: font.family).contains(font.name) {
|
||||||
|
font.register()
|
||||||
|
}
|
||||||
|
#elseif os(macOS)
|
||||||
|
if let url = font.url, CTFontManagerGetScopeForURL(url as CFURL) == .none {
|
||||||
|
font.register()
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
self.init(name: font.name, size: size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No fonts found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,157 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if platform and storyboards %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
|
||||||
|
{% set prefix %}{% if isAppKit %}NS{% else %}UI{% endif %}{% endset %}
|
||||||
|
{% set controller %}{% if isAppKit %}Controller{% else %}ViewController{% endif %}{% endset %}
|
||||||
|
// swiftlint:disable sorted_imports
|
||||||
|
import Foundation
|
||||||
|
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
|
||||||
|
import {{module}}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Storyboard Scenes
|
||||||
|
|
||||||
|
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||||
|
{% macro moduleName item %}{% filter removeNewlines %}
|
||||||
|
{% if item.moduleIsPlaceholder %}
|
||||||
|
{{ env.PRODUCT_MODULE_NAME|default:param.module }}
|
||||||
|
{% else %}
|
||||||
|
{{ item.module }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro className item %}{% filter removeNewlines %}
|
||||||
|
{% set module %}{% call moduleName item %}{% endset %}
|
||||||
|
{% if module and ( not param.ignoreTargetModule or module != env.PRODUCT_MODULE_NAME and module != param.module ) %}
|
||||||
|
{{module}}.
|
||||||
|
{% endif %}
|
||||||
|
{{item.type}}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"StoryboardScene"}} {
|
||||||
|
{% for storyboard in storyboards %}
|
||||||
|
{% set storyboardName %}{{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}{% endset %}
|
||||||
|
{{accessModifier}} enum {{storyboardName}}: StoryboardType {
|
||||||
|
{{accessModifier}} static let storyboardName = "{{storyboard.name}}"
|
||||||
|
{% if storyboard.initialScene %}
|
||||||
|
|
||||||
|
{% set sceneClass %}{% call className storyboard.initialScene %}{% endset %}
|
||||||
|
{{accessModifier}} static let initialScene = InitialSceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self)
|
||||||
|
{% endif %}
|
||||||
|
{% for scene in storyboard.scenes %}
|
||||||
|
|
||||||
|
{% set sceneID %}{{scene.identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set sceneClass %}{% call className scene %}{% endset %}
|
||||||
|
{{accessModifier}} static let {{sceneID}} = SceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self, identifier: "{{scene.identifier}}")
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
{{accessModifier}} protocol StoryboardType {
|
||||||
|
static var storyboardName: String { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension StoryboardType {
|
||||||
|
static var storyboard: {{prefix}}Storyboard {
|
||||||
|
let name = {% if isAppKit %}NSStoryboard.Name({% endif %}self.storyboardName{% if isAppKit %}){% endif %}
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
return {{param.lookupFunction}}(name)
|
||||||
|
{% else %}
|
||||||
|
return {{prefix}}Storyboard(name: name, bundle: {{param.bundle|default:"BundleToken.bundle"}})
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} struct SceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
|
||||||
|
{{accessModifier}} let storyboard: StoryboardType.Type
|
||||||
|
{{accessModifier}} let identifier: String
|
||||||
|
|
||||||
|
{{accessModifier}} func instantiate() -> T {
|
||||||
|
let identifier = {% if isAppKit %}NSStoryboard.SceneIdentifier({% endif %}self.identifier{% if isAppKit %}){% endif %}
|
||||||
|
guard let controller = storyboard.storyboard.instantiate{{controller}}(withIdentifier: identifier) as? T else {
|
||||||
|
fatalError("{{controller}} '\(identifier)' is not of the expected class \(T.self).")
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if isAppKit %}
|
||||||
|
@available(macOS 10.15, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
|
||||||
|
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 10.15, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
|
||||||
|
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
|
@available(iOS 13.0, tvOS 13.0, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
|
||||||
|
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} struct InitialSceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
|
||||||
|
{{accessModifier}} let storyboard: StoryboardType.Type
|
||||||
|
|
||||||
|
{{accessModifier}} func instantiate() -> T {
|
||||||
|
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}() as? T else {
|
||||||
|
fatalError("{{controller}} is not of the expected class \(T.self).")
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if isAppKit %}
|
||||||
|
@available(macOS 10.15, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
|
||||||
|
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||||
|
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 10.15, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
|
||||||
|
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||||
|
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
|
@available(iOS 13.0, tvOS 13.0, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
|
||||||
|
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||||
|
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% elif storyboards %}
|
||||||
|
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
|
||||||
|
{% else %}
|
||||||
|
// No storyboard found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,159 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if platform and storyboards %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
|
||||||
|
{% set prefix %}{% if isAppKit %}NS{% else %}UI{% endif %}{% endset %}
|
||||||
|
{% set controller %}{% if isAppKit %}Controller{% else %}ViewController{% endif %}{% endset %}
|
||||||
|
// swiftlint:disable sorted_imports
|
||||||
|
import Foundation
|
||||||
|
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
|
||||||
|
import {{module}}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Storyboard Scenes
|
||||||
|
|
||||||
|
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||||
|
{% macro moduleName item %}{% filter removeNewlines %}
|
||||||
|
{% if item.moduleIsPlaceholder %}
|
||||||
|
{{ env.PRODUCT_MODULE_NAME|default:param.module }}
|
||||||
|
{% else %}
|
||||||
|
{{ item.module }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro className item %}{% filter removeNewlines %}
|
||||||
|
{% set module %}{% call moduleName item %}{% endset %}
|
||||||
|
{% if module and ( not param.ignoreTargetModule or module != env.PRODUCT_MODULE_NAME and module != param.module ) %}
|
||||||
|
{{module}}.
|
||||||
|
{% endif %}
|
||||||
|
{{item.type}}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"StoryboardScene"}} {
|
||||||
|
{% for storyboard in storyboards %}
|
||||||
|
{% set storyboardName %}{{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}{% endset %}
|
||||||
|
{{accessModifier}} enum {{storyboardName}}: StoryboardType {
|
||||||
|
{{accessModifier}} static let storyboardName = "{{storyboard.name}}"
|
||||||
|
{% if storyboard.initialScene %}
|
||||||
|
|
||||||
|
{% set sceneClass %}{% call className storyboard.initialScene %}{% endset %}
|
||||||
|
{{accessModifier}} static let initialScene = InitialSceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self)
|
||||||
|
{% endif %}
|
||||||
|
{% for scene in storyboard.scenes %}
|
||||||
|
|
||||||
|
{% set sceneID %}{{scene.identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set sceneClass %}{% call className scene %}{% endset %}
|
||||||
|
{{accessModifier}} static let {{sceneID}} = SceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self, identifier: "{{scene.identifier}}")
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
{{accessModifier}} protocol StoryboardType {
|
||||||
|
static var storyboardName: String { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension StoryboardType {
|
||||||
|
static var storyboard: {{prefix}}Storyboard {
|
||||||
|
let name = {% if isAppKit %}NSStoryboard.Name({% endif %}self.storyboardName{% if isAppKit %}){% endif %}
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
return {{param.lookupFunction}}(name)
|
||||||
|
{% else %}
|
||||||
|
return {{prefix}}Storyboard(name: name, bundle: {{param.bundle|default:"BundleToken.bundle"}})
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} struct SceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
|
||||||
|
{{accessModifier}} let storyboard: StoryboardType.Type
|
||||||
|
{{accessModifier}} let identifier: String
|
||||||
|
|
||||||
|
{{accessModifier}} func instantiate() -> T {
|
||||||
|
let identifier = {% if isAppKit %}NSStoryboard.SceneIdentifier({% endif %}self.identifier{% if isAppKit %}){% endif %}
|
||||||
|
guard let controller = storyboard.storyboard.instantiate{{controller}}(withIdentifier: identifier) as? T else {
|
||||||
|
fatalError("{{controller}} '\(identifier)' is not of the expected class \(T.self).")
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if isAppKit %}
|
||||||
|
@available(macOS 10.15, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
|
||||||
|
let identifier = NSStoryboard.SceneIdentifier(self.identifier)
|
||||||
|
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 10.15, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
|
||||||
|
let identifier = NSStoryboard.SceneIdentifier(self.identifier)
|
||||||
|
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
|
@available(iOS 13.0, tvOS 13.0, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
|
||||||
|
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} struct InitialSceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
|
||||||
|
{{accessModifier}} let storyboard: StoryboardType.Type
|
||||||
|
|
||||||
|
{{accessModifier}} func instantiate() -> T {
|
||||||
|
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}() as? T else {
|
||||||
|
fatalError("{{controller}} is not of the expected class \(T.self).")
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if isAppKit %}
|
||||||
|
@available(macOS 10.15, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
|
||||||
|
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||||
|
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 10.15, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
|
||||||
|
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||||
|
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
|
@available(iOS 13.0, tvOS 13.0, *)
|
||||||
|
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
|
||||||
|
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||||
|
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% elif storyboards %}
|
||||||
|
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
|
||||||
|
{% else %}
|
||||||
|
// No storyboard found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,60 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if platform and storyboards %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
|
||||||
|
// swiftlint:disable sorted_imports
|
||||||
|
import Foundation
|
||||||
|
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
|
||||||
|
import {{module}}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - Storyboard Segues
|
||||||
|
|
||||||
|
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"StoryboardSegue"}} {
|
||||||
|
{% for storyboard in storyboards where storyboard.segues %}
|
||||||
|
{{accessModifier}} enum {{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}: String, SegueType {
|
||||||
|
{% for segue in storyboard.segues %}
|
||||||
|
{% set segueID %}{{segue.identifier|swiftIdentifier:"pretty"|lowerFirstWord}}{% endset %}
|
||||||
|
case {{segueID|escapeReservedKeywords}}{% if segueID != segue.identifier %} = "{{segue.identifier}}"{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
{{accessModifier}} protocol SegueType: RawRepresentable {}
|
||||||
|
|
||||||
|
{{accessModifier}} extension {% if isAppKit %}NSSeguePerforming{% else %}UIViewController{% endif %} {
|
||||||
|
func perform<S: SegueType>(segue: S, sender: Any? = nil) where S.RawValue == String {
|
||||||
|
let identifier = {% if isAppKit %}NSStoryboardSegue.Identifier({% endif %}segue.rawValue{% if isAppKit %}){% endif %}
|
||||||
|
performSegue{% if isAppKit %}?{% endif %}(withIdentifier: identifier, sender: sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension SegueType where RawValue == String {
|
||||||
|
init?(_ segue: {% if isAppKit %}NS{% else %}UI{% endif %}StoryboardSegue) {
|
||||||
|
{% if isAppKit %}
|
||||||
|
#if swift(>=4.2)
|
||||||
|
guard let identifier = segue.identifier else { return nil }
|
||||||
|
#else
|
||||||
|
guard let identifier = segue.identifier?.rawValue else { return nil }
|
||||||
|
#endif
|
||||||
|
{% else %}
|
||||||
|
guard let identifier = segue.identifier else { return nil }
|
||||||
|
{% endif %}
|
||||||
|
self.init(rawValue: identifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% elif storyboards %}
|
||||||
|
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
|
||||||
|
{% else %}
|
||||||
|
// No storyboard found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,60 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if platform and storyboards %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
|
||||||
|
// swiftlint:disable sorted_imports
|
||||||
|
import Foundation
|
||||||
|
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
|
||||||
|
import {{module}}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - Storyboard Segues
|
||||||
|
|
||||||
|
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"StoryboardSegue"}} {
|
||||||
|
{% for storyboard in storyboards where storyboard.segues %}
|
||||||
|
{{accessModifier}} enum {{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}: String, SegueType {
|
||||||
|
{% for segue in storyboard.segues %}
|
||||||
|
{% set segueID %}{{segue.identifier|swiftIdentifier:"pretty"|lowerFirstWord}}{% endset %}
|
||||||
|
case {{segueID|escapeReservedKeywords}}{% if segueID != segue.identifier %} = "{{segue.identifier}}"{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
{{accessModifier}} protocol SegueType: RawRepresentable {}
|
||||||
|
|
||||||
|
{{accessModifier}} extension {% if isAppKit %}NSSeguePerforming{% else %}UIViewController{% endif %} {
|
||||||
|
func perform<S: SegueType>(segue: S, sender: Any? = nil) where S.RawValue == String {
|
||||||
|
let identifier = {% if isAppKit %}NSStoryboardSegue.Identifier({% endif %}segue.rawValue{% if isAppKit %}){% endif %}
|
||||||
|
performSegue{% if isAppKit %}?{% endif %}(withIdentifier: identifier, sender: sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension SegueType where RawValue == String {
|
||||||
|
init?(_ segue: {% if isAppKit %}NS{% else %}UI{% endif %}StoryboardSegue) {
|
||||||
|
{% if isAppKit %}
|
||||||
|
#if swift(>=4.2)
|
||||||
|
guard let identifier = segue.identifier else { return nil }
|
||||||
|
#else
|
||||||
|
guard let identifier = segue.identifier?.rawValue else { return nil }
|
||||||
|
#endif
|
||||||
|
{% else %}
|
||||||
|
guard let identifier = segue.identifier else { return nil }
|
||||||
|
{% endif %}
|
||||||
|
self.init(rawValue: identifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% elif storyboards %}
|
||||||
|
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
|
||||||
|
{% else %}
|
||||||
|
// No storyboard found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,82 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - JSON Files
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
{% call documentBlock file file.document %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro documentBlock file document %}
|
||||||
|
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||||
|
{% if document.metadata.type == "Array" %}
|
||||||
|
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% elif document.metadata.type == "Dictionary" %}
|
||||||
|
{% for key,value in document.metadata.properties %}
|
||||||
|
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "Array" %}
|
||||||
|
[{% call typeBlock metadata.element %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
Any?
|
||||||
|
{% else %}
|
||||||
|
{{metadata.type}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||||
|
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "String" %}
|
||||||
|
"{{ value }}"
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
nil
|
||||||
|
{% elif metadata.type == "Array" and value %}
|
||||||
|
[{% for value in value %}
|
||||||
|
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[{% for key,value in value %}
|
||||||
|
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% empty %}
|
||||||
|
:
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Bool" %}
|
||||||
|
{% if value %}true{% else %}false{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{{ value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
|
||||||
|
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for file in files %}
|
||||||
|
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call fileBlock files.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,82 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - JSON Files
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
{% call documentBlock file file.document %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro documentBlock file document %}
|
||||||
|
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||||
|
{% if document.metadata.type == "Array" %}
|
||||||
|
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% elif document.metadata.type == "Dictionary" %}
|
||||||
|
{% for key,value in document.metadata.properties %}
|
||||||
|
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "Array" %}
|
||||||
|
[{% call typeBlock metadata.element %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
Any?
|
||||||
|
{% else %}
|
||||||
|
{{metadata.type}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||||
|
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "String" %}
|
||||||
|
"{{ value }}"
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
nil
|
||||||
|
{% elif metadata.type == "Array" and value %}
|
||||||
|
[{% for value in value %}
|
||||||
|
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[{% for key,value in value %}
|
||||||
|
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% empty %}
|
||||||
|
:
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Bool" %}
|
||||||
|
{% if value %}true{% else %}false{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{{ value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
|
||||||
|
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for file in files %}
|
||||||
|
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call fileBlock files.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,112 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - JSON Files
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
{% call documentBlock file file.document %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro documentBlock file document %}
|
||||||
|
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||||
|
{% if document.metadata.type == "Array" %}
|
||||||
|
{{accessModifier}} static let items: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
|
||||||
|
{% elif document.metadata.type == "Dictionary" %}
|
||||||
|
private static let _document = JSONDocument(path: "{% call transformPath file.path %}")
|
||||||
|
|
||||||
|
{% for key,value in document.metadata.properties %}
|
||||||
|
{{accessModifier}} {% call propertyBlock key value %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let value: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "Array" %}
|
||||||
|
[{% call typeBlock metadata.element %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
Any?
|
||||||
|
{% else %}
|
||||||
|
{{metadata.type}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||||
|
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro transformPath path %}{% filter removeNewlines %}
|
||||||
|
{% if param.preservePath %}
|
||||||
|
{{path}}
|
||||||
|
{% else %}
|
||||||
|
{{path|basename}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
|
||||||
|
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for file in files %}
|
||||||
|
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call fileBlock files.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
private func objectFromJSON<T>(at path: String) -> T {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
guard let url = {{param.lookupFunction}}(path),
|
||||||
|
{% else %}
|
||||||
|
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||||
|
{% endif %}
|
||||||
|
let json = try? JSONSerialization.jsonObject(with: Data(contentsOf: url), options: []),
|
||||||
|
let result = json as? T else {
|
||||||
|
fatalError("Unable to load JSON at path: \(path)")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct JSONDocument {
|
||||||
|
let data: [String: Any]
|
||||||
|
|
||||||
|
init(path: String) {
|
||||||
|
self.data = objectFromJSON(at: path)
|
||||||
|
}
|
||||||
|
|
||||||
|
subscript<T>(key: String) -> T {
|
||||||
|
guard let result = data[key] as? T else {
|
||||||
|
fatalError("Property '\(key)' is not of type \(T.self)")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,112 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - JSON Files
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
{% call documentBlock file file.document %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro documentBlock file document %}
|
||||||
|
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||||
|
{% if document.metadata.type == "Array" %}
|
||||||
|
{{accessModifier}} static let items: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
|
||||||
|
{% elif document.metadata.type == "Dictionary" %}
|
||||||
|
private static let _document = JSONDocument(path: "{% call transformPath file.path %}")
|
||||||
|
|
||||||
|
{% for key,value in document.metadata.properties %}
|
||||||
|
{{accessModifier}} {% call propertyBlock key value %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let value: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "Array" %}
|
||||||
|
[{% call typeBlock metadata.element %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
Any?
|
||||||
|
{% else %}
|
||||||
|
{{metadata.type}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||||
|
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro transformPath path %}{% filter removeNewlines %}
|
||||||
|
{% if param.preservePath %}
|
||||||
|
{{path}}
|
||||||
|
{% else %}
|
||||||
|
{{path|basename}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
|
||||||
|
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for file in files %}
|
||||||
|
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call fileBlock files.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
private func objectFromJSON<T>(at path: String) -> T {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
guard let url = {{param.lookupFunction}}(path),
|
||||||
|
{% else %}
|
||||||
|
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||||
|
{% endif %}
|
||||||
|
let json = try? JSONSerialization.jsonObject(with: Data(contentsOf: url), options: []),
|
||||||
|
let result = json as? T else {
|
||||||
|
fatalError("Unable to load JSON at path: \(path)")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct JSONDocument {
|
||||||
|
let data: [String: Any]
|
||||||
|
|
||||||
|
init(path: String) {
|
||||||
|
self.data = objectFromJSON(at: path)
|
||||||
|
}
|
||||||
|
|
||||||
|
subscript<T>(key: String) -> T {
|
||||||
|
guard let result = data[key] as? T else {
|
||||||
|
fatalError("Property '\(key)' is not of type \(T.self)")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,82 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - Plist Files
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
{% call documentBlock file file.document %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro documentBlock file document %}
|
||||||
|
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||||
|
{% if document.metadata.type == "Array" %}
|
||||||
|
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% elif document.metadata.type == "Dictionary" %}
|
||||||
|
{% for key,value in document.metadata.properties %}
|
||||||
|
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "Array" %}
|
||||||
|
[{% call typeBlock metadata.element %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% else %}
|
||||||
|
{{metadata.type}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||||
|
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "String" %}
|
||||||
|
"{{ value }}"
|
||||||
|
{% elif metadata.type == "Date" %}
|
||||||
|
Date(timeIntervalSinceReferenceDate: {{ value.timeIntervalSinceReferenceDate }})
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
nil
|
||||||
|
{% elif metadata.type == "Array" and value %}
|
||||||
|
[{% for value in value %}
|
||||||
|
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[{% for key,value in value %}
|
||||||
|
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% empty %}
|
||||||
|
:
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Bool" %}
|
||||||
|
{% if value %}true{% else %}false{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{{ value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
|
||||||
|
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for file in files %}
|
||||||
|
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call fileBlock files.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,82 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - Plist Files
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
{% call documentBlock file file.document %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro documentBlock file document %}
|
||||||
|
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||||
|
{% if document.metadata.type == "Array" %}
|
||||||
|
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% elif document.metadata.type == "Dictionary" %}
|
||||||
|
{% for key,value in document.metadata.properties %}
|
||||||
|
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "Array" %}
|
||||||
|
[{% call typeBlock metadata.element %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% else %}
|
||||||
|
{{metadata.type}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||||
|
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "String" %}
|
||||||
|
"{{ value }}"
|
||||||
|
{% elif metadata.type == "Date" %}
|
||||||
|
Date(timeIntervalSinceReferenceDate: {{ value.timeIntervalSinceReferenceDate }})
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
nil
|
||||||
|
{% elif metadata.type == "Array" and value %}
|
||||||
|
[{% for value in value %}
|
||||||
|
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[{% for key,value in value %}
|
||||||
|
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% empty %}
|
||||||
|
:
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Bool" %}
|
||||||
|
{% if value %}true{% else %}false{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{{ value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
|
||||||
|
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for file in files %}
|
||||||
|
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call fileBlock files.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,117 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - Plist Files
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
{% call documentBlock file file.document %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro documentBlock file document %}
|
||||||
|
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||||
|
{% if document.metadata.type == "Array" %}
|
||||||
|
{{accessModifier}} static let items: {{rootType}} = arrayFromPlist(at: "{% call transformPath file.path %}")
|
||||||
|
{% elif document.metadata.type == "Dictionary" %}
|
||||||
|
private static let _document = PlistDocument(path: "{% call transformPath file.path %}")
|
||||||
|
|
||||||
|
{% for key,value in document.metadata.properties %}
|
||||||
|
{{accessModifier}} {% call propertyBlock key value %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
// Unsupported root type `{{rootType}}`
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "Array" %}
|
||||||
|
[{% call typeBlock metadata.element %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% else %}
|
||||||
|
{{metadata.type}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||||
|
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro transformPath path %}{% filter removeNewlines %}
|
||||||
|
{% if param.preservePath %}
|
||||||
|
{{path}}
|
||||||
|
{% else %}
|
||||||
|
{{path|basename}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
|
||||||
|
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for file in files %}
|
||||||
|
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call fileBlock files.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
private func arrayFromPlist<T>(at path: String) -> [T] {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
guard let url = {{param.lookupFunction}}(path),
|
||||||
|
{% else %}
|
||||||
|
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||||
|
{% endif %}
|
||||||
|
let data = NSArray(contentsOf: url) as? [T] else {
|
||||||
|
fatalError("Unable to load PLIST at path: \(path)")
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct PlistDocument {
|
||||||
|
let data: [String: Any]
|
||||||
|
|
||||||
|
init(path: String) {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
guard let url = {{param.lookupFunction}}(path),
|
||||||
|
{% else %}
|
||||||
|
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||||
|
{% endif %}
|
||||||
|
let data = NSDictionary(contentsOf: url) as? [String: Any] else {
|
||||||
|
fatalError("Unable to load PLIST at path: \(path)")
|
||||||
|
}
|
||||||
|
self.data = data
|
||||||
|
}
|
||||||
|
|
||||||
|
subscript<T>(key: String) -> T {
|
||||||
|
guard let result = data[key] as? T else {
|
||||||
|
fatalError("Property '\(key)' is not of type \(T.self)")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,117 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - Plist Files
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
{% call documentBlock file file.document %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro documentBlock file document %}
|
||||||
|
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||||
|
{% if document.metadata.type == "Array" %}
|
||||||
|
{{accessModifier}} static let items: {{rootType}} = arrayFromPlist(at: "{% call transformPath file.path %}")
|
||||||
|
{% elif document.metadata.type == "Dictionary" %}
|
||||||
|
private static let _document = PlistDocument(path: "{% call transformPath file.path %}")
|
||||||
|
|
||||||
|
{% for key,value in document.metadata.properties %}
|
||||||
|
{{accessModifier}} {% call propertyBlock key value %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
// Unsupported root type `{{rootType}}`
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "Array" %}
|
||||||
|
[{% call typeBlock metadata.element %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% else %}
|
||||||
|
{{metadata.type}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||||
|
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro transformPath path %}{% filter removeNewlines %}
|
||||||
|
{% if param.preservePath %}
|
||||||
|
{{path}}
|
||||||
|
{% else %}
|
||||||
|
{{path|basename}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length type_body_length
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
|
||||||
|
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for file in files %}
|
||||||
|
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call fileBlock files.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length type_body_length
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
private func arrayFromPlist<T>(at path: String) -> [T] {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
guard let url = {{param.lookupFunction}}(path),
|
||||||
|
{% else %}
|
||||||
|
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||||
|
{% endif %}
|
||||||
|
let data = NSArray(contentsOf: url) as? [T] else {
|
||||||
|
fatalError("Unable to load PLIST at path: \(path)")
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct PlistDocument {
|
||||||
|
let data: [String: Any]
|
||||||
|
|
||||||
|
init(path: String) {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
guard let url = {{param.lookupFunction}}(path),
|
||||||
|
{% else %}
|
||||||
|
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||||
|
{% endif %}
|
||||||
|
let data = NSDictionary(contentsOf: url) as? [String: Any] else {
|
||||||
|
fatalError("Unable to load PLIST at path: \(path)")
|
||||||
|
}
|
||||||
|
self.data = data
|
||||||
|
}
|
||||||
|
|
||||||
|
subscript<T>(key: String) -> T {
|
||||||
|
guard let result = data[key] as? T else {
|
||||||
|
fatalError("Property '\(key)' is not of type \(T.self)")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,99 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if tables.count > 0 %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Strings
|
||||||
|
|
||||||
|
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
{% if type == "String" %}
|
||||||
|
_ p{{forloop.counter}}: Any
|
||||||
|
{% else %}
|
||||||
|
_ p{{forloop.counter}}: {{type}}
|
||||||
|
{% endif %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
{% if type == "String" %}
|
||||||
|
String(describing: p{{forloop.counter}})
|
||||||
|
{% elif type == "UnsafeRawPointer" %}
|
||||||
|
Int(bitPattern: p{{forloop.counter}})
|
||||||
|
{% else %}
|
||||||
|
p{{forloop.counter}}
|
||||||
|
{% endif %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro recursiveBlock table item %}
|
||||||
|
{% for string in item.strings %}
|
||||||
|
{% if not param.noComments %}
|
||||||
|
{% for line in string.translation|split:"\n" %}
|
||||||
|
/// {{line}}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if string.types %}
|
||||||
|
{{accessModifier}} static func {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
|
||||||
|
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
|
||||||
|
}
|
||||||
|
{% elif param.lookupFunction %}
|
||||||
|
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
|
||||||
|
{{accessModifier}} static var {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for child in item.children %}
|
||||||
|
{% call recursiveBlock table child %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
// swiftlint:disable function_parameter_count identifier_name line_length type_body_length
|
||||||
|
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
|
||||||
|
{{accessModifier}} enum {{enumName}} {
|
||||||
|
{% if tables.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for table in tables %}
|
||||||
|
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call recursiveBlock tables.first.name tables.first.levels %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable function_parameter_count identifier_name line_length type_body_length
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
extension {{enumName}} {
|
||||||
|
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
let format = {{ param.lookupFunction }}(key, table)
|
||||||
|
{% else %}
|
||||||
|
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
|
||||||
|
{% endif %}
|
||||||
|
return String(format: format, locale: Locale.current, arguments: args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No string found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,99 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if tables.count > 0 %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Strings
|
||||||
|
|
||||||
|
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
{% if type == "String" %}
|
||||||
|
_ p{{forloop.counter}}: Any
|
||||||
|
{% else %}
|
||||||
|
_ p{{forloop.counter}}: {{type}}
|
||||||
|
{% endif %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
{% if type == "String" %}
|
||||||
|
String(describing: p{{forloop.counter}})
|
||||||
|
{% elif type == "UnsafeRawPointer" %}
|
||||||
|
Int(bitPattern: p{{forloop.counter}})
|
||||||
|
{% else %}
|
||||||
|
p{{forloop.counter}}
|
||||||
|
{% endif %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro recursiveBlock table item %}
|
||||||
|
{% for string in item.strings %}
|
||||||
|
{% if not param.noComments %}
|
||||||
|
{% for line in string.translation|split:"\n" %}
|
||||||
|
/// {{line}}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if string.types %}
|
||||||
|
{{accessModifier}} static func {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
|
||||||
|
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
|
||||||
|
}
|
||||||
|
{% elif param.lookupFunction %}
|
||||||
|
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
|
||||||
|
{{accessModifier}} static var {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for child in item.children %}
|
||||||
|
{% call recursiveBlock table child %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
// swiftlint:disable function_parameter_count identifier_name line_length type_body_length
|
||||||
|
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
|
||||||
|
{{accessModifier}} enum {{enumName}} {
|
||||||
|
{% if tables.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for table in tables %}
|
||||||
|
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call recursiveBlock tables.first.name tables.first.levels %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable function_parameter_count identifier_name line_length type_body_length
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
extension {{enumName}} {
|
||||||
|
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
let format = {{ param.lookupFunction }}(key, table)
|
||||||
|
{% else %}
|
||||||
|
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
|
||||||
|
{% endif %}
|
||||||
|
return String(format: format, locale: Locale.current, arguments: args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No string found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,68 @@
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if tables.count > 0 %}
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
({% call paramTranslate type %})p{{ forloop.counter }}{{ " :" if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
p{{forloop.counter}}{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro paramTranslate swiftType %}
|
||||||
|
{% if swiftType == "Any" %}
|
||||||
|
id
|
||||||
|
{% elif swiftType == "CChar" %}
|
||||||
|
char
|
||||||
|
{% elif swiftType == "Float" %}
|
||||||
|
float
|
||||||
|
{% elif swiftType == "Int" %}
|
||||||
|
NSInteger
|
||||||
|
{% elif swiftType == "String" %}
|
||||||
|
id
|
||||||
|
{% elif swiftType == "UnsafePointer<CChar>" %}
|
||||||
|
char*
|
||||||
|
{% elif swiftType == "UnsafeRawPointer" %}
|
||||||
|
void*
|
||||||
|
{% else %}
|
||||||
|
objc-h.stencil is missing '{{swiftType}}'
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro emitOneMethod table item %}
|
||||||
|
{% for string in item.strings %}
|
||||||
|
{% if not param.noComments %}
|
||||||
|
{% for line in string.translation|split:"\n" %}
|
||||||
|
/// {{line}}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if string.types %}
|
||||||
|
{% if string.types.count == 1 %}
|
||||||
|
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValue:{% call parametersBlock string.types %};
|
||||||
|
{% else %}
|
||||||
|
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValues:{% call parametersBlock string.types %};
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}};
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for child in item.children %}
|
||||||
|
{% call emitOneMethod table child %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% for table in tables %}
|
||||||
|
@interface {{ table.name }} : NSObject
|
||||||
|
{% call emitOneMethod table.name table.levels %}
|
||||||
|
@end
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
{% else %}
|
||||||
|
// No strings found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,90 @@
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if tables.count > 0 %}
|
||||||
|
#import "{{ param.headerName|default:"Localizable.h" }}"
|
||||||
|
{% if not param.bundle %}
|
||||||
|
|
||||||
|
@interface BundleToken : NSObject
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation BundleToken
|
||||||
|
@end
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wformat-security"
|
||||||
|
|
||||||
|
static NSString* tr(NSString *tableName, NSString *key, ...) {
|
||||||
|
NSBundle *bundle = {{param.bundle|default:"[NSBundle bundleForClass:BundleToken.class]"}};
|
||||||
|
NSString *format = [bundle localizedStringForKey:key value:nil table:tableName];
|
||||||
|
NSLocale *locale = [NSLocale currentLocale];
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, key);
|
||||||
|
NSString *result = [[NSString alloc] initWithFormat:format locale:locale arguments:args];
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
|
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
({% call paramTranslate type %})p{{ forloop.counter }}{{ " :" if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
p{{forloop.counter}}{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro paramTranslate swiftType %}
|
||||||
|
{% if swiftType == "Any" %}
|
||||||
|
id
|
||||||
|
{% elif swiftType == "CChar" %}
|
||||||
|
char
|
||||||
|
{% elif swiftType == "Float" %}
|
||||||
|
float
|
||||||
|
{% elif swiftType == "Int" %}
|
||||||
|
NSInteger
|
||||||
|
{% elif swiftType == "String" %}
|
||||||
|
id
|
||||||
|
{% elif swiftType == "UnsafePointer<CChar>" %}
|
||||||
|
char*
|
||||||
|
{% elif swiftType == "UnsafeRawPointer" %}
|
||||||
|
void*
|
||||||
|
{% else %}
|
||||||
|
objc-m.stencil is missing '{{swiftType}}'
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro tableContents table item %}
|
||||||
|
{% for string in item.strings %}
|
||||||
|
{% if string.types %}
|
||||||
|
{% if string.types.count == 1 %}
|
||||||
|
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValue:{% call parametersBlock string.types %}
|
||||||
|
{% else %}
|
||||||
|
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValues:{% call parametersBlock string.types %}
|
||||||
|
{% endif %}
|
||||||
|
{
|
||||||
|
return tr(@"{{table}}", @"{{string.key}}", {% call argumentsBlock string.types %});
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
|
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}} {
|
||||||
|
return tr(@"{{table}}", @"{{string.key}}");
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for child in item.children %}
|
||||||
|
{% call tableContents table child %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% for table in tables %}
|
||||||
|
{% set tableName %}{{table.name|default:"Localized"}}{% endset %}
|
||||||
|
@implementation {{ tableName }} : NSObject
|
||||||
|
{% call tableContents table.name table.levels %}
|
||||||
|
@end
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
// No strings found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,104 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if tables.count > 0 %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Strings
|
||||||
|
|
||||||
|
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
{% if type == "String" %}
|
||||||
|
_ p{{forloop.counter}}: Any
|
||||||
|
{% else %}
|
||||||
|
_ p{{forloop.counter}}: {{type}}
|
||||||
|
{% endif %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
{% if type == "String" %}
|
||||||
|
String(describing: p{{forloop.counter}})
|
||||||
|
{% elif type == "UnsafeRawPointer" %}
|
||||||
|
Int(bitPattern: p{{forloop.counter}})
|
||||||
|
{% else %}
|
||||||
|
p{{forloop.counter}}
|
||||||
|
{% endif %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro recursiveBlock table item %}
|
||||||
|
{% for string in item.strings %}
|
||||||
|
{% if not param.noComments %}
|
||||||
|
{% for line in string.translation|split:"\n" %}
|
||||||
|
/// {{line}}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if string.types %}
|
||||||
|
{{accessModifier}} static func {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
|
||||||
|
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
|
||||||
|
}
|
||||||
|
{% elif param.lookupFunction %}
|
||||||
|
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
|
||||||
|
{{accessModifier}} static var {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for child in item.children %}
|
||||||
|
|
||||||
|
{{accessModifier}} enum {{child.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call recursiveBlock table child %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
|
||||||
|
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
|
||||||
|
{{accessModifier}} enum {{enumName}} {
|
||||||
|
{% if tables.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for table in tables %}
|
||||||
|
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call recursiveBlock tables.first.name tables.first.levels %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
|
||||||
|
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
extension {{enumName}} {
|
||||||
|
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
let format = {{ param.lookupFunction }}(key, table)
|
||||||
|
{% else %}
|
||||||
|
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
|
||||||
|
{% endif %}
|
||||||
|
return String(format: format, locale: Locale.current, arguments: args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No string found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,104 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if tables.count > 0 %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Strings
|
||||||
|
|
||||||
|
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
{% if type == "String" %}
|
||||||
|
_ p{{forloop.counter}}: Any
|
||||||
|
{% else %}
|
||||||
|
_ p{{forloop.counter}}: {{type}}
|
||||||
|
{% endif %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% for type in types %}
|
||||||
|
{% if type == "String" %}
|
||||||
|
String(describing: p{{forloop.counter}})
|
||||||
|
{% elif type == "UnsafeRawPointer" %}
|
||||||
|
Int(bitPattern: p{{forloop.counter}})
|
||||||
|
{% else %}
|
||||||
|
p{{forloop.counter}}
|
||||||
|
{% endif %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro recursiveBlock table item %}
|
||||||
|
{% for string in item.strings %}
|
||||||
|
{% if not param.noComments %}
|
||||||
|
{% for line in string.translation|split:"\n" %}
|
||||||
|
/// {{line}}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if string.types %}
|
||||||
|
{{accessModifier}} static func {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
|
||||||
|
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
|
||||||
|
}
|
||||||
|
{% elif param.lookupFunction %}
|
||||||
|
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
|
||||||
|
{{accessModifier}} static var {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for child in item.children %}
|
||||||
|
|
||||||
|
{{accessModifier}} enum {{child.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call recursiveBlock table child %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
|
||||||
|
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
|
||||||
|
{{accessModifier}} enum {{enumName}} {
|
||||||
|
{% if tables.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for table in tables %}
|
||||||
|
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call recursiveBlock tables.first.name tables.first.levels %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
|
||||||
|
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
|
||||||
|
extension {{enumName}} {
|
||||||
|
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||||
|
{% if param.lookupFunction %}
|
||||||
|
let format = {{ param.lookupFunction }}(key, table)
|
||||||
|
{% else %}
|
||||||
|
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
|
||||||
|
{% endif %}
|
||||||
|
return String(format: format, locale: Locale.current, arguments: args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% if not param.bundle and not param.lookupFunction %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No string found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,329 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if catalogs %}
|
||||||
|
{% set enumName %}{{param.enumName|default:"Asset"}}{% endset %}
|
||||||
|
{% set arResourceGroupType %}{{param.arResourceGroupTypeName|default:"ARResourceGroupAsset"}}{% endset %}
|
||||||
|
{% set colorType %}{{param.colorTypeName|default:"ColorAsset"}}{% endset %}
|
||||||
|
{% set dataType %}{{param.dataTypeName|default:"DataAsset"}}{% endset %}
|
||||||
|
{% set imageType %}{{param.imageTypeName|default:"ImageAsset"}}{% endset %}
|
||||||
|
{% set symbolType %}{{param.symbolTypeName|default:"SymbolAsset"}}{% endset %}
|
||||||
|
{% set forceNamespaces %}{{param.forceProvidesNamespaces|default:"false"}}{% endset %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
#if os(macOS)
|
||||||
|
import AppKit
|
||||||
|
#elseif os(iOS)
|
||||||
|
{% if resourceCount.arresourcegroup > 0 %}
|
||||||
|
import ARKit
|
||||||
|
{% endif %}
|
||||||
|
import UIKit
|
||||||
|
#elseif os(tvOS) || os(watchOS)
|
||||||
|
import UIKit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Deprecated typealiases
|
||||||
|
{% if resourceCount.color > 0 %}
|
||||||
|
@available(*, deprecated, renamed: "{{colorType}}.Color", message: "This typealias will be removed in SwiftGen 7.0")
|
||||||
|
{{accessModifier}} typealias {{param.colorAliasName|default:"AssetColorTypeAlias"}} = {{colorType}}.Color
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.image > 0 %}
|
||||||
|
@available(*, deprecated, renamed: "{{imageType}}.Image", message: "This typealias will be removed in SwiftGen 7.0")
|
||||||
|
{{accessModifier}} typealias {{param.imageAliasName|default:"AssetImageTypeAlias"}} = {{imageType}}.Image
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Asset Catalogs
|
||||||
|
|
||||||
|
{% macro enumBlock assets %}
|
||||||
|
{% call casesBlock assets %}
|
||||||
|
{% if param.allValues %}
|
||||||
|
|
||||||
|
// swiftlint:disable trailing_comma
|
||||||
|
{% if resourceCount.arresourcegroup > 0 %}
|
||||||
|
{{accessModifier}} static let allResourceGroups: [{{arResourceGroupType}}] = [
|
||||||
|
{% filter indent:2 %}{% call allValuesBlock assets "arresourcegroup" "" %}{% endfilter %}
|
||||||
|
]
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.color > 0 %}
|
||||||
|
{{accessModifier}} static let allColors: [{{colorType}}] = [
|
||||||
|
{% filter indent:2 %}{% call allValuesBlock assets "color" "" %}{% endfilter %}
|
||||||
|
]
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.data > 0 %}
|
||||||
|
{{accessModifier}} static let allDataAssets: [{{dataType}}] = [
|
||||||
|
{% filter indent:2 %}{% call allValuesBlock assets "data" "" %}{% endfilter %}
|
||||||
|
]
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.image > 0 %}
|
||||||
|
{{accessModifier}} static let allImages: [{{imageType}}] = [
|
||||||
|
{% filter indent:2 %}{% call allValuesBlock assets "image" "" %}{% endfilter %}
|
||||||
|
]
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.symbol > 0 %}
|
||||||
|
{{accessModifier}} static let allSymbols: [{{symbolType}}] = [
|
||||||
|
{% filter indent:2 %}{% call allValuesBlock assets "symbol" "" %}{% endfilter %}
|
||||||
|
]
|
||||||
|
{% endif %}
|
||||||
|
// swiftlint:enable trailing_comma
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro casesBlock assets %}
|
||||||
|
{% for asset in assets %}
|
||||||
|
{% if asset.type == "arresourcegroup" %}
|
||||||
|
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{arResourceGroupType}}(name: "{{asset.value}}")
|
||||||
|
{% elif asset.type == "color" %}
|
||||||
|
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{colorType}}(name: "{{asset.value}}")
|
||||||
|
{% elif asset.type == "data" %}
|
||||||
|
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{dataType}}(name: "{{asset.value}}")
|
||||||
|
{% elif asset.type == "image" %}
|
||||||
|
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{imageType}}(name: "{{asset.value}}")
|
||||||
|
{% elif asset.type == "symbol" %}
|
||||||
|
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{symbolType}}(name: "{{asset.value}}")
|
||||||
|
{% elif asset.items and ( forceNamespaces == "true" or asset.isNamespaced == "true" ) %}
|
||||||
|
{{accessModifier}} enum {{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call casesBlock asset.items %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% elif asset.items %}
|
||||||
|
{% call casesBlock asset.items %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro allValuesBlock assets filter prefix %}
|
||||||
|
{% for asset in assets %}
|
||||||
|
{% if asset.type == filter %}
|
||||||
|
{{prefix}}{{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}},
|
||||||
|
{% elif asset.items and ( forceNamespaces == "true" or asset.isNamespaced == "true" ) %}
|
||||||
|
{% set prefix2 %}{{prefix}}{{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.{% endset %}
|
||||||
|
{% call allValuesBlock asset.items filter prefix2 %}
|
||||||
|
{% elif asset.items %}
|
||||||
|
{% call allValuesBlock asset.items filter prefix %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
|
||||||
|
{{accessModifier}} enum {{enumName}} {
|
||||||
|
{% if catalogs.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for catalog in catalogs %}
|
||||||
|
{{accessModifier}} enum {{catalog.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call enumBlock catalog.assets %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call enumBlock catalogs.first.assets %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length nesting type_body_length type_name
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
{% if resourceCount.arresourcegroup > 0 %}
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{arResourceGroupType}} {
|
||||||
|
{{accessModifier}} fileprivate(set) var name: String
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
@available(iOS 11.3, *)
|
||||||
|
{{accessModifier}} var referenceImages: Set<ARReferenceImage> {
|
||||||
|
return ARReferenceImage.referenceImages(in: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 12.0, *)
|
||||||
|
{{accessModifier}} var referenceObjects: Set<ARReferenceObject> {
|
||||||
|
return ARReferenceObject.referenceObjects(in: self)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
@available(iOS 11.3, *)
|
||||||
|
{{accessModifier}} extension ARReferenceImage {
|
||||||
|
static func referenceImages(in asset: {{arResourceGroupType}}) -> Set<ARReferenceImage> {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
return referenceImages(inGroupNamed: asset.name, bundle: bundle) ?? Set()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 12.0, *)
|
||||||
|
{{accessModifier}} extension ARReferenceObject {
|
||||||
|
static func referenceObjects(in asset: {{arResourceGroupType}}) -> Set<ARReferenceObject> {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
return referenceObjects(inGroupNamed: asset.name, bundle: bundle) ?? Set()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.color > 0 %}
|
||||||
|
|
||||||
|
{{accessModifier}} final class {{colorType}} {
|
||||||
|
{{accessModifier}} fileprivate(set) var name: String
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
|
{{accessModifier}} typealias Color = NSColor
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
{{accessModifier}} typealias Color = UIColor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
|
||||||
|
{{accessModifier}} private(set) lazy var color: Color = Color(asset: self)
|
||||||
|
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
@available(iOS 11.0, tvOS 11.0, *)
|
||||||
|
{{accessModifier}} func color(compatibleWith traitCollection: UITraitCollection) -> Color {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
guard let color = Color(named: name, in: bundle, compatibleWith: traitCollection) else {
|
||||||
|
fatalError("Unable to load color asset named \(name).")
|
||||||
|
}
|
||||||
|
return color
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fileprivate init(name: String) {
|
||||||
|
self.name = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension {{colorType}}.Color {
|
||||||
|
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
|
||||||
|
convenience init!(asset: {{colorType}}) {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
self.init(named: asset.name, in: bundle, compatibleWith: nil)
|
||||||
|
#elseif os(macOS)
|
||||||
|
self.init(named: NSColor.Name(asset.name), bundle: bundle)
|
||||||
|
#elseif os(watchOS)
|
||||||
|
self.init(named: asset.name)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.data > 0 %}
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{dataType}} {
|
||||||
|
{{accessModifier}} fileprivate(set) var name: String
|
||||||
|
|
||||||
|
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
|
||||||
|
{{accessModifier}} var data: NSDataAsset {
|
||||||
|
return NSDataAsset(asset: self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
|
||||||
|
{{accessModifier}} extension NSDataAsset {
|
||||||
|
convenience init!(asset: {{dataType}}) {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
self.init(name: asset.name, bundle: bundle)
|
||||||
|
#elseif os(macOS)
|
||||||
|
self.init(name: NSDataAsset.Name(asset.name), bundle: bundle)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.image > 0 %}
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{imageType}} {
|
||||||
|
{{accessModifier}} fileprivate(set) var name: String
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
|
{{accessModifier}} typealias Image = NSImage
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
{{accessModifier}} typealias Image = UIImage
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, macOS 10.7, *)
|
||||||
|
{{accessModifier}} var image: Image {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||||
|
#elseif os(macOS)
|
||||||
|
let name = NSImage.Name(self.name)
|
||||||
|
let image = (bundle == .main) ? NSImage(named: name) : bundle.image(forResource: name)
|
||||||
|
#elseif os(watchOS)
|
||||||
|
let image = Image(named: name)
|
||||||
|
#endif
|
||||||
|
guard let result = image else {
|
||||||
|
fatalError("Unable to load image asset named \(name).")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
@available(iOS 8.0, tvOS 9.0, *)
|
||||||
|
{{accessModifier}} func image(compatibleWith traitCollection: UITraitCollection) -> Image {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
guard let result = Image(named: name, in: bundle, compatibleWith: traitCollection) else {
|
||||||
|
fatalError("Unable to load image asset named \(name).")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension {{imageType}}.Image {
|
||||||
|
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, *)
|
||||||
|
@available(macOS, deprecated,
|
||||||
|
message: "This initializer is unsafe on macOS, please use the {{imageType}}.image property")
|
||||||
|
convenience init!(asset: {{imageType}}) {
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
self.init(named: asset.name, in: bundle, compatibleWith: nil)
|
||||||
|
#elseif os(macOS)
|
||||||
|
self.init(named: NSImage.Name(asset.name))
|
||||||
|
#elseif os(watchOS)
|
||||||
|
self.init(named: asset.name)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.symbol > 0 %}
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{symbolType}} {
|
||||||
|
{{accessModifier}} fileprivate(set) var name: String
|
||||||
|
|
||||||
|
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||||
|
{{accessModifier}} typealias Configuration = UIImage.SymbolConfiguration
|
||||||
|
{{accessModifier}} typealias Image = UIImage
|
||||||
|
|
||||||
|
@available(iOS 12.0, tvOS 12.0, watchOS 5.0, *)
|
||||||
|
{{accessModifier}} var image: Image {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||||
|
#elseif os(watchOS)
|
||||||
|
let image = Image(named: name)
|
||||||
|
#endif
|
||||||
|
guard let result = image else {
|
||||||
|
fatalError("Unable to load symbol asset named \(name).")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||||
|
{{accessModifier}} func image(with configuration: Configuration) -> Image {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
guard let result = Image(named: name, in: bundle, with: configuration) else {
|
||||||
|
fatalError("Unable to load symbol asset named \(name).")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% if not param.bundle %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No assets found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,337 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if catalogs %}
|
||||||
|
{% set enumName %}{{param.enumName|default:"Asset"}}{% endset %}
|
||||||
|
{% set arResourceGroupType %}{{param.arResourceGroupTypeName|default:"ARResourceGroupAsset"}}{% endset %}
|
||||||
|
{% set colorType %}{{param.colorTypeName|default:"ColorAsset"}}{% endset %}
|
||||||
|
{% set dataType %}{{param.dataTypeName|default:"DataAsset"}}{% endset %}
|
||||||
|
{% set imageType %}{{param.imageTypeName|default:"ImageAsset"}}{% endset %}
|
||||||
|
{% set symbolType %}{{param.symbolTypeName|default:"SymbolAsset"}}{% endset %}
|
||||||
|
{% set forceNamespaces %}{{param.forceProvidesNamespaces|default:"false"}}{% endset %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
#if os(macOS)
|
||||||
|
import AppKit
|
||||||
|
#elseif os(iOS)
|
||||||
|
{% if resourceCount.arresourcegroup > 0 %}
|
||||||
|
import ARKit
|
||||||
|
{% endif %}
|
||||||
|
import UIKit
|
||||||
|
#elseif os(tvOS) || os(watchOS)
|
||||||
|
import UIKit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Deprecated typealiases
|
||||||
|
{% if resourceCount.color > 0 %}
|
||||||
|
@available(*, deprecated, renamed: "{{colorType}}.Color", message: "This typealias will be removed in SwiftGen 7.0")
|
||||||
|
{{accessModifier}} typealias {{param.colorAliasName|default:"AssetColorTypeAlias"}} = {{colorType}}.Color
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.image > 0 %}
|
||||||
|
@available(*, deprecated, renamed: "{{imageType}}.Image", message: "This typealias will be removed in SwiftGen 7.0")
|
||||||
|
{{accessModifier}} typealias {{param.imageAliasName|default:"AssetImageTypeAlias"}} = {{imageType}}.Image
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||||
|
|
||||||
|
// MARK: - Asset Catalogs
|
||||||
|
|
||||||
|
{% macro enumBlock assets %}
|
||||||
|
{% call casesBlock assets %}
|
||||||
|
{% if param.allValues %}
|
||||||
|
|
||||||
|
// swiftlint:disable trailing_comma
|
||||||
|
{% if resourceCount.arresourcegroup > 0 %}
|
||||||
|
{{accessModifier}} static let allResourceGroups: [{{arResourceGroupType}}] = [
|
||||||
|
{% filter indent:2 %}{% call allValuesBlock assets "arresourcegroup" "" %}{% endfilter %}
|
||||||
|
]
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.color > 0 %}
|
||||||
|
{{accessModifier}} static let allColors: [{{colorType}}] = [
|
||||||
|
{% filter indent:2 %}{% call allValuesBlock assets "color" "" %}{% endfilter %}
|
||||||
|
]
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.data > 0 %}
|
||||||
|
{{accessModifier}} static let allDataAssets: [{{dataType}}] = [
|
||||||
|
{% filter indent:2 %}{% call allValuesBlock assets "data" "" %}{% endfilter %}
|
||||||
|
]
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.image > 0 %}
|
||||||
|
{{accessModifier}} static let allImages: [{{imageType}}] = [
|
||||||
|
{% filter indent:2 %}{% call allValuesBlock assets "image" "" %}{% endfilter %}
|
||||||
|
]
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.symbol > 0 %}
|
||||||
|
{{accessModifier}} static let allSymbols: [{{symbolType}}] = [
|
||||||
|
{% filter indent:2 %}{% call allValuesBlock assets "symbol" "" %}{% endfilter %}
|
||||||
|
]
|
||||||
|
{% endif %}
|
||||||
|
// swiftlint:enable trailing_comma
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro casesBlock assets %}
|
||||||
|
{% for asset in assets %}
|
||||||
|
{% if asset.type == "arresourcegroup" %}
|
||||||
|
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{arResourceGroupType}}(name: "{{asset.value}}")
|
||||||
|
{% elif asset.type == "color" %}
|
||||||
|
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{colorType}}(name: "{{asset.value}}")
|
||||||
|
{% elif asset.type == "data" %}
|
||||||
|
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{dataType}}(name: "{{asset.value}}")
|
||||||
|
{% elif asset.type == "image" %}
|
||||||
|
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{imageType}}(name: "{{asset.value}}")
|
||||||
|
{% elif asset.type == "symbol" %}
|
||||||
|
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{symbolType}}(name: "{{asset.value}}")
|
||||||
|
{% elif asset.items and ( forceNamespaces == "true" or asset.isNamespaced == "true" ) %}
|
||||||
|
{{accessModifier}} enum {{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call casesBlock asset.items %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% elif asset.items %}
|
||||||
|
{% call casesBlock asset.items %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro allValuesBlock assets filter prefix %}
|
||||||
|
{% for asset in assets %}
|
||||||
|
{% if asset.type == filter %}
|
||||||
|
{{prefix}}{{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}},
|
||||||
|
{% elif asset.items and ( forceNamespaces == "true" or asset.isNamespaced == "true" ) %}
|
||||||
|
{% set prefix2 %}{{prefix}}{{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.{% endset %}
|
||||||
|
{% call allValuesBlock asset.items filter prefix2 %}
|
||||||
|
{% elif asset.items %}
|
||||||
|
{% call allValuesBlock asset.items filter prefix %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
|
||||||
|
{{accessModifier}} enum {{enumName}} {
|
||||||
|
{% if catalogs.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for catalog in catalogs %}
|
||||||
|
{{accessModifier}} enum {{catalog.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call enumBlock catalog.assets %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call enumBlock catalogs.first.assets %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length nesting type_body_length type_name
|
||||||
|
|
||||||
|
// MARK: - Implementation Details
|
||||||
|
{% if resourceCount.arresourcegroup > 0 %}
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{arResourceGroupType}} {
|
||||||
|
{{accessModifier}} fileprivate(set) var name: String
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
@available(iOS 11.3, *)
|
||||||
|
{{accessModifier}} var referenceImages: Set<ARReferenceImage> {
|
||||||
|
return ARReferenceImage.referenceImages(in: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 12.0, *)
|
||||||
|
{{accessModifier}} var referenceObjects: Set<ARReferenceObject> {
|
||||||
|
return ARReferenceObject.referenceObjects(in: self)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
@available(iOS 11.3, *)
|
||||||
|
{{accessModifier}} extension ARReferenceImage {
|
||||||
|
static func referenceImages(in asset: {{arResourceGroupType}}) -> Set<ARReferenceImage> {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
return referenceImages(inGroupNamed: asset.name, bundle: bundle) ?? Set()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 12.0, *)
|
||||||
|
{{accessModifier}} extension ARReferenceObject {
|
||||||
|
static func referenceObjects(in asset: {{arResourceGroupType}}) -> Set<ARReferenceObject> {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
return referenceObjects(inGroupNamed: asset.name, bundle: bundle) ?? Set()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.color > 0 %}
|
||||||
|
|
||||||
|
{{accessModifier}} final class {{colorType}} {
|
||||||
|
{{accessModifier}} fileprivate(set) var name: String
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
|
{{accessModifier}} typealias Color = NSColor
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
{{accessModifier}} typealias Color = UIColor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
|
||||||
|
{{accessModifier}} private(set) lazy var color: Color = {
|
||||||
|
guard let color = Color(asset: self) else {
|
||||||
|
fatalError("Unable to load color asset named \(name).")
|
||||||
|
}
|
||||||
|
return color
|
||||||
|
}()
|
||||||
|
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
@available(iOS 11.0, tvOS 11.0, *)
|
||||||
|
{{accessModifier}} func color(compatibleWith traitCollection: UITraitCollection) -> Color {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
guard let color = Color(named: name, in: bundle, compatibleWith: traitCollection) else {
|
||||||
|
fatalError("Unable to load color asset named \(name).")
|
||||||
|
}
|
||||||
|
return color
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fileprivate init(name: String) {
|
||||||
|
self.name = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension {{colorType}}.Color {
|
||||||
|
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
|
||||||
|
convenience init?(asset: {{colorType}}) {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
self.init(named: asset.name, in: bundle, compatibleWith: nil)
|
||||||
|
#elseif os(macOS)
|
||||||
|
self.init(named: NSColor.Name(asset.name), bundle: bundle)
|
||||||
|
#elseif os(watchOS)
|
||||||
|
self.init(named: asset.name)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.data > 0 %}
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{dataType}} {
|
||||||
|
{{accessModifier}} fileprivate(set) var name: String
|
||||||
|
|
||||||
|
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
|
||||||
|
{{accessModifier}} var data: NSDataAsset {
|
||||||
|
guard let data = NSDataAsset(asset: self) else {
|
||||||
|
fatalError("Unable to load data asset named \(name).")
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
|
||||||
|
{{accessModifier}} extension NSDataAsset {
|
||||||
|
convenience init?(asset: {{dataType}}) {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
self.init(name: asset.name, bundle: bundle)
|
||||||
|
#elseif os(macOS)
|
||||||
|
self.init(name: NSDataAsset.Name(asset.name), bundle: bundle)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.image > 0 %}
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{imageType}} {
|
||||||
|
{{accessModifier}} fileprivate(set) var name: String
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
|
{{accessModifier}} typealias Image = NSImage
|
||||||
|
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
{{accessModifier}} typealias Image = UIImage
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, macOS 10.7, *)
|
||||||
|
{{accessModifier}} var image: Image {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||||
|
#elseif os(macOS)
|
||||||
|
let name = NSImage.Name(self.name)
|
||||||
|
let image = (bundle == .main) ? NSImage(named: name) : bundle.image(forResource: name)
|
||||||
|
#elseif os(watchOS)
|
||||||
|
let image = Image(named: name)
|
||||||
|
#endif
|
||||||
|
guard let result = image else {
|
||||||
|
fatalError("Unable to load image asset named \(name).")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
@available(iOS 8.0, tvOS 9.0, *)
|
||||||
|
{{accessModifier}} func image(compatibleWith traitCollection: UITraitCollection) -> Image {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
guard let result = Image(named: name, in: bundle, compatibleWith: traitCollection) else {
|
||||||
|
fatalError("Unable to load image asset named \(name).")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
{{accessModifier}} extension {{imageType}}.Image {
|
||||||
|
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, *)
|
||||||
|
@available(macOS, deprecated,
|
||||||
|
message: "This initializer is unsafe on macOS, please use the {{imageType}}.image property")
|
||||||
|
convenience init?(asset: {{imageType}}) {
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
self.init(named: asset.name, in: bundle, compatibleWith: nil)
|
||||||
|
#elseif os(macOS)
|
||||||
|
self.init(named: NSImage.Name(asset.name))
|
||||||
|
#elseif os(watchOS)
|
||||||
|
self.init(named: asset.name)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% if resourceCount.symbol > 0 %}
|
||||||
|
|
||||||
|
{{accessModifier}} struct {{symbolType}} {
|
||||||
|
{{accessModifier}} fileprivate(set) var name: String
|
||||||
|
|
||||||
|
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||||
|
{{accessModifier}} typealias Configuration = UIImage.SymbolConfiguration
|
||||||
|
{{accessModifier}} typealias Image = UIImage
|
||||||
|
|
||||||
|
@available(iOS 12.0, tvOS 12.0, watchOS 5.0, *)
|
||||||
|
{{accessModifier}} var image: Image {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
|
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||||
|
#elseif os(watchOS)
|
||||||
|
let image = Image(named: name)
|
||||||
|
#endif
|
||||||
|
guard let result = image else {
|
||||||
|
fatalError("Unable to load symbol asset named \(name).")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||||
|
{{accessModifier}} func image(with configuration: Configuration) -> Image {
|
||||||
|
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||||
|
guard let result = Image(named: name, in: bundle, with: configuration) else {
|
||||||
|
fatalError("Unable to load symbol asset named \(name).")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% if not param.bundle %}
|
||||||
|
|
||||||
|
// swiftlint:disable convenience_type
|
||||||
|
private final class BundleToken {
|
||||||
|
static let bundle: Bundle = {
|
||||||
|
#if SWIFT_PACKAGE
|
||||||
|
return Bundle.module
|
||||||
|
#else
|
||||||
|
return Bundle(for: BundleToken.self)
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// swiftlint:enable convenience_type
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
// No assets found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,92 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set documentPrefix %}{{param.documentName|default:"Document"}}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - YAML Files
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
{% if file.documents.count > 1 %}
|
||||||
|
{% for document in file.documents %}
|
||||||
|
{% set documentName %}{{documentPrefix}}{{forloop.counter}}{% endset %}
|
||||||
|
{{accessModifier}} enum {{documentName|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call documentBlock file document %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call documentBlock file file.documents.first %}
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro documentBlock file document %}
|
||||||
|
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||||
|
{% if document.metadata.type == "Array" %}
|
||||||
|
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% elif document.metadata.type == "Dictionary" %}
|
||||||
|
{% for key,value in document.metadata.properties %}
|
||||||
|
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "Array" %}
|
||||||
|
[{% call typeBlock metadata.element %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
Any?
|
||||||
|
{% else %}
|
||||||
|
{{metadata.type}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||||
|
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "String" %}
|
||||||
|
"{{ value }}"
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
nil
|
||||||
|
{% elif metadata.type == "Array" and value %}
|
||||||
|
[{% for value in value %}
|
||||||
|
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[{% for key,value in value %}
|
||||||
|
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% empty %}
|
||||||
|
:
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Bool" %}
|
||||||
|
{% if value %}true{% else %}false{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{{ value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"YAMLFiles"}} {
|
||||||
|
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for file in files %}
|
||||||
|
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call fileBlock files.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,92 @@
|
||||||
|
// swiftlint:disable all
|
||||||
|
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||||
|
{% set documentPrefix %}{{param.documentName|default:"Document"}}{% endset %}
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// swiftlint:disable superfluous_disable_command
|
||||||
|
// swiftlint:disable file_length
|
||||||
|
|
||||||
|
// MARK: - YAML Files
|
||||||
|
{% macro fileBlock file %}
|
||||||
|
{% if file.documents.count > 1 %}
|
||||||
|
{% for document in file.documents %}
|
||||||
|
{% set documentName %}{{documentPrefix}}{{forloop.counter}}{% endset %}
|
||||||
|
{{accessModifier}} enum {{documentName|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call documentBlock file document %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call documentBlock file file.documents.first %}
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro documentBlock file document %}
|
||||||
|
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||||
|
{% if document.metadata.type == "Array" %}
|
||||||
|
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% elif document.metadata.type == "Dictionary" %}
|
||||||
|
{% for key,value in document.metadata.properties %}
|
||||||
|
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "Array" %}
|
||||||
|
[{% call typeBlock metadata.element %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[String: Any]
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
Any?
|
||||||
|
{% else %}
|
||||||
|
{{metadata.type}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||||
|
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||||
|
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||||
|
{% if metadata.type == "String" %}
|
||||||
|
"{{ value }}"
|
||||||
|
{% elif metadata.type == "Optional" %}
|
||||||
|
nil
|
||||||
|
{% elif metadata.type == "Array" and value %}
|
||||||
|
[{% for value in value %}
|
||||||
|
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Dictionary" %}
|
||||||
|
[{% for key,value in value %}
|
||||||
|
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||||
|
{{ ", " if not forloop.last }}
|
||||||
|
{% empty %}
|
||||||
|
:
|
||||||
|
{% endfor %}]
|
||||||
|
{% elif metadata.type == "Bool" %}
|
||||||
|
{% if value %}true{% else %}false{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{{ value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfilter %}{% endmacro %}
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||||
|
{{accessModifier}} enum {{param.enumName|default:"YAMLFiles"}} {
|
||||||
|
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||||
|
{% for file in files %}
|
||||||
|
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||||
|
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% call fileBlock files.first %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||||
|
{% else %}
|
||||||
|
// No files found
|
||||||
|
{% endif %}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
||||||
|
strings:
|
||||||
|
inputs: Translations/en.lproj
|
||||||
|
outputs:
|
||||||
|
- templateName: structured-swift5
|
||||||
|
output: Shared/Generated/Strings.swift
|
Loading…
Reference in New Issue