Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Modules/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ let package = Package(
name: "PocketCastsUtils",
targets: ["PocketCastsUtils"]
),
.library(
name: "PocketCastsSharedModels",
targets: ["PocketCastsSharedModels"]
),
.library(
name: "PocketCastsDataModel",
targets: ["PocketCastsDataModel"]
Expand Down Expand Up @@ -105,6 +109,15 @@ let package = Package(
dependencies: ["PocketCastsUtils"],
path: "Tests/PocketCastsUtilsTests"
),
.target(
name: "PocketCastsSharedModels",
path: "Sources/PocketCastsSharedModels"
),
.testTarget(
name: "PocketCastsSharedModelsTests",
dependencies: ["PocketCastsSharedModels"],
path: "Tests/PocketCastsSharedModelsTests"
),
.target(
name: "PocketCastsDataModel",
dependencies: [
Expand Down Expand Up @@ -215,6 +228,7 @@ enum XcodeSupport {
"PocketCastsDataModel",
"PocketCastsServer",
"PocketCastsUtils",
"PocketCastsSharedModels",
"PocketCastsDependencyInjection",
"EventHorizonSDK",
.product(name: "Lottie", package: "lottie-ios"),
Expand Down Expand Up @@ -273,6 +287,7 @@ enum XcodeSupport {
.xcodeTarget(
XcodeTargetNames.podcastsIntents,
dependencies: [
"PocketCastsSharedModels",
.product(name: "Fuse", package: "fuse-swift"),
]
),
Expand All @@ -286,6 +301,7 @@ enum XcodeSupport {
XcodeTargetNames.widgetExtension,
dependencies: [
"PocketCastsUtils",
"PocketCastsSharedModels",
]
),
.xcodeTarget(
Expand Down
29 changes: 29 additions & 0 deletions Modules/Sources/PocketCastsSharedModels/CommonUpNextItem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Foundation

public struct CommonUpNextItem: Codable, Hashable {
public var episodeUuid: String
public var imageUrl: String
public var episodeTitle: String
public var podcastName: String
public var podcastColor: String
public var duration: TimeInterval
public var isPlaying: Bool

public init(
episodeUuid: String,
imageUrl: String,
episodeTitle: String,
podcastName: String,
podcastColor: String,
duration: TimeInterval,
isPlaying: Bool = false
) {
self.episodeUuid = episodeUuid
self.imageUrl = imageUrl
self.episodeTitle = episodeTitle
self.podcastName = podcastName
self.podcastColor = podcastColor
self.duration = duration
self.isPlaying = isPlaying
}
}
11 changes: 11 additions & 0 deletions Modules/Sources/PocketCastsSharedModels/SiriPodcastItem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation

public struct SiriPodcastItem: Codable {
public var name: String
public var uuid: String

public init(name: String, uuid: String) {
self.name = name
self.uuid = uuid
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Foundation
@testable import PocketCastsSharedModels
import XCTest

final class CommonUpNextItemTests: XCTestCase {
// CommonUpNextItem crosses process boundaries via App Group UserDefaults
// (main app writes, widget/intents extension reads). The Codable contract
// is the wire format — guard it explicitly.
func testRoundTripsThroughJSONCoding() throws {
let original = CommonUpNextItem(
episodeUuid: "episode-uuid",
imageUrl: "https://example.com/image.png",
episodeTitle: "Episode Title",
podcastName: "Podcast Name",
podcastColor: "#FF0000",
duration: 1234.5,
isPlaying: true
)

let data = try JSONEncoder().encode(original)
let decoded = try JSONDecoder().decode(CommonUpNextItem.self, from: data)

XCTAssertEqual(decoded, original)
}

func testRoundTripsWhenNotPlaying() throws {
let original = CommonUpNextItem(
episodeUuid: "uuid",
imageUrl: "url",
episodeTitle: "title",
podcastName: "name",
podcastColor: "color",
duration: 0,
isPlaying: false
)

let data = try JSONEncoder().encode(original)
let decoded = try JSONDecoder().decode(CommonUpNextItem.self, from: data)

XCTAssertEqual(decoded, original)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Foundation
@testable import PocketCastsSharedModels
import XCTest

final class SiriPodcastItemTests: XCTestCase {
// SiriPodcastItem crosses the boundary between the main app and the
// PodcastsIntents extension. The Codable contract is the wire format.
func testRoundTripsThroughJSONCoding() throws {
let original = SiriPodcastItem(name: "Podcast Name", uuid: "podcast-uuid")

let data = try JSONEncoder().encode(original)
let decoded = try JSONDecoder().decode(SiriPodcastItem.self, from: data)

XCTAssertEqual(decoded.name, original.name)
XCTAssertEqual(decoded.uuid, original.uuid)
}
}
7 changes: 7 additions & 0 deletions PocketCastsTests/UnitTests.xctestplan
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@
"identifier" : "PocketCastsUtilsTests",
"name" : "PocketCastsUtilsTests"
}
},
{
"target" : {
"containerPath" : "container:Modules",
"identifier" : "PocketCastsSharedModelsTests",
"name" : "PocketCastsSharedModelsTests"
}
}
],
"version" : 1
Expand Down
1 change: 1 addition & 0 deletions PodcastsIntents/PlayMediaIntentHandler.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import CoreSpotlight
import Intents
import MediaPlayer
import PocketCastsSharedModels
import UIKit

class PlayMediaIntentHandler: NSObject, INPlayMediaIntentHandling {
Expand Down
1 change: 1 addition & 0 deletions PodcastsIntents/SiriPodcastSearchManager.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation
import Fuse
import PocketCastsSharedModels

class SiriPodcastSearchManager {
func matchUtteranceToPodcast(searchString: String) -> SiriPodcastItem? {
Expand Down
1 change: 1 addition & 0 deletions WidgetExtension/Common/CommonWidgetHelper.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import PocketCastsSharedModels
import PocketCastsUtils
import UIKit

Expand Down
1 change: 1 addition & 0 deletions WidgetExtension/Data/WidgetEpisode.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import PocketCastsSharedModels
import SwiftUI

class WidgetEpisode: ObservableObject, Hashable {
Expand Down
3 changes: 2 additions & 1 deletion WidgetExtension/Now Playing/NowPlayingEntryView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Foundation
import WidgetKit
import PocketCastsSharedModels
import SwiftUI
import WidgetKit

struct NowPlayingWidgetEntryView: View {
@State var entry: NowPlayingProvider.Entry
Expand Down
16 changes: 0 additions & 16 deletions podcasts.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@
3FC668CA2F7CD51E0072EBA8 /* XcodeTarget_WidgetExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 3FC668C92F7CD51E0072EBA8 /* XcodeTarget_WidgetExtension */; };
3FC668CC2F7CD5A20072EBA8 /* XcodeTarget_Pocket Casts App Clip in Frameworks */ = {isa = PBXBuildFile; productRef = 3FC668CB2F7CD5A20072EBA8 /* XcodeTarget_Pocket Casts App Clip */; };
4000A2A025463C6A00356FCE /* LeftAlignedFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4000A29F25463C6900356FCE /* LeftAlignedFlowLayout.swift */; };
40043F0B23FBC6B1004A9B57 /* SiriPodcastItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40043F0A23FBC6B1004A9B57 /* SiriPodcastItem.swift */; };
40043F0D23FDFD91004A9B57 /* SiriPodcastItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40043F0A23FBC6B1004A9B57 /* SiriPodcastItem.swift */; };
40043F0F23FE08B8004A9B57 /* SharedConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD054A791E3EDEB300D9195B /* SharedConstants.swift */; };
40043F1123FE0A05004A9B57 /* SiriPodcastItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40043F0A23FBC6B1004A9B57 /* SiriPodcastItem.swift */; };
40043F1323FE0D9E004A9B57 /* SharedConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD054A791E3EDEB300D9195B /* SharedConstants.swift */; };
4006E30B23A35F1500174DEB /* CollectionSummaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4006E30923A35F1500174DEB /* CollectionSummaryViewController.swift */; };
4006E30C23A35F1500174DEB /* CollectionSummaryViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4006E30A23A35F1500174DEB /* CollectionSummaryViewController.xib */; };
Expand Down Expand Up @@ -105,10 +102,8 @@
4029E3E42293AD410003BEEB /* ChangePasswordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4029E3E22293AD410003BEEB /* ChangePasswordViewController.swift */; };
4029E3E52293AD410003BEEB /* ChangePasswordViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4029E3E32293AD410003BEEB /* ChangePasswordViewController.xib */; };
403086D02378EB1F009EF821 /* UpNextViewController+UserEpisode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 403086CF2378EB1F009EF821 /* UpNextViewController+UserEpisode.swift */; };
40334805240C83D200EE338E /* CommonUpNextItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD44A4442302DAC6004F55B2 /* CommonUpNextItem.swift */; };
4034503324BF33B6001265E2 /* ListeningHistoryViewController+MultiSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4034503224BF33B4001265E2 /* ListeningHistoryViewController+MultiSelect.swift */; };
4036B06E25240CC600AE08E6 /* SharedConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD054A791E3EDEB300D9195B /* SharedConstants.swift */; };
4036B09325240CD100AE08E6 /* CommonUpNextItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD44A4442302DAC6004F55B2 /* CommonUpNextItem.swift */; };
4036B0A425240F5D00AE08E6 /* WidgetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4036B0A325240F5D00AE08E6 /* WidgetHelper.swift */; };
403946E72285231100F55162 /* AddCustomViewController+ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 403946E62285231100F55162 /* AddCustomViewController+ImagePicker.swift */; };
403946E9228587FC00F55162 /* AddCustomViewController+CollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 403946E8228587FC00F55162 /* AddCustomViewController+CollectionView.swift */; };
Expand Down Expand Up @@ -614,7 +609,6 @@
BD42E31A1B940AFF000EA14F /* DiscoverPodcastTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD42E3181B940AFF000EA14F /* DiscoverPodcastTableCell.swift */; };
BD42E31B1B940AFF000EA14F /* DiscoverPodcastTableCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BD42E3191B940AFF000EA14F /* DiscoverPodcastTableCell.xib */; };
BD43BDE72122AD0600E63165 /* skip_button.json in Resources */ = {isa = PBXBuildFile; fileRef = BD43BDE52122AD0600E63165 /* skip_button.json */; };
BD44A4452302DAC6004F55B2 /* CommonUpNextItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD44A4442302DAC6004F55B2 /* CommonUpNextItem.swift */; };
BD44E36D20937D9C008BD7F0 /* PodcastChapterParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD44E36C20937D9C008BD7F0 /* PodcastChapterParser.swift */; };
BD47E7FA1DD57F7B00C18EE7 /* ShowNotesFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD47E7F91DD57F7B00C18EE7 /* ShowNotesFormatter.swift */; };
BD48D5A6216DB26A00391F9E /* HapticsHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD48D5A5216DB26A00391F9E /* HapticsHelper.swift */; };
Expand Down Expand Up @@ -1558,7 +1552,6 @@
2F90990B2A4F88B00044FC55 /* Share Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Share Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
3FD6E04F2BF735EC003941C0 /* podcasts.prototype.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = podcasts.prototype.entitlements; sourceTree = "<group>"; };
4000A29F25463C6900356FCE /* LeftAlignedFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftAlignedFlowLayout.swift; sourceTree = "<group>"; };
40043F0A23FBC6B1004A9B57 /* SiriPodcastItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiriPodcastItem.swift; sourceTree = "<group>"; };
4006E30923A35F1500174DEB /* CollectionSummaryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionSummaryViewController.swift; sourceTree = "<group>"; };
4006E30A23A35F1500174DEB /* CollectionSummaryViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CollectionSummaryViewController.xib; sourceTree = "<group>"; };
4006E30F23A88AE600174DEB /* ExpandedCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandedCollectionViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2130,7 +2123,6 @@
BD42E3181B940AFF000EA14F /* DiscoverPodcastTableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiscoverPodcastTableCell.swift; sourceTree = "<group>"; };
BD42E3191B940AFF000EA14F /* DiscoverPodcastTableCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DiscoverPodcastTableCell.xib; sourceTree = "<group>"; };
BD43BDE52122AD0600E63165 /* skip_button.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = skip_button.json; sourceTree = "<group>"; };
BD44A4442302DAC6004F55B2 /* CommonUpNextItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonUpNextItem.swift; sourceTree = "<group>"; };
BD44E36C20937D9C008BD7F0 /* PodcastChapterParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PodcastChapterParser.swift; sourceTree = "<group>"; };
BD47E7F91DD57F7B00C18EE7 /* ShowNotesFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShowNotesFormatter.swift; sourceTree = "<group>"; };
BD48D5A5216DB26A00391F9E /* HapticsHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticsHelper.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3680,7 +3672,6 @@
8BC0600A2AB1FB8100A4FEC6 /* AppPlayEpisodeIntentExtension.swift */,
8BC060072AB1FA0400A4FEC6 /* PlayEpisodeIntent.swift */,
BD054A791E3EDEB300D9195B /* SharedConstants.swift */,
40043F0A23FBC6B1004A9B57 /* SiriPodcastItem.swift */,
8BC0600C2AB2218300A4FEC6 /* WidgetPlayEpisodeIntentExtension.swift */,
);
name = "Shared with Extension";
Expand Down Expand Up @@ -3936,7 +3927,6 @@
BDF15A451B54E21B000EC323 /* PlaybackEffects.swift */,
8BB4AA622BD17EC10091480A /* FadeOutManager.swift */,
8B1B782A2BC7104000DC3373 /* SleepTimerManager.swift */,
BD44A4442302DAC6004F55B2 /* CommonUpNextItem.swift */,
BD2219F0253EAEAF000025BE /* PlaybackCatchUpHelper.swift */,
C725285E299B315000A582C3 /* BookmarkManager.swift */,
);
Expand Down Expand Up @@ -6683,9 +6673,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
40043F0D23FDFD91004A9B57 /* SiriPodcastItem.swift in Sources */,
46FBD8B6276A874F00867746 /* Intents.intentdefinition in Sources */,
40334805240C83D200EE338E /* CommonUpNextItem.swift in Sources */,
40043F0F23FE08B8004A9B57 /* SharedConstants.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -6694,7 +6682,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
40043F1123FE0A05004A9B57 /* SiriPodcastItem.swift in Sources */,
40043F1323FE0D9E004A9B57 /* SharedConstants.swift in Sources */,
46FBD8B7276A874F00867746 /* Intents.intentdefinition in Sources */,
);
Expand All @@ -6711,7 +6698,6 @@
8BC0600E2AB2219700A4FEC6 /* WidgetPlayEpisodeIntentExtension.swift in Sources */,
8BC060092AB1FA0D00A4FEC6 /* PlayEpisodeIntent.swift in Sources */,
463538F526F2415300BA9D35 /* Strings+L10n.swift in Sources */,
4036B09325240CD100AE08E6 /* CommonUpNextItem.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -7256,7 +7242,6 @@
FF9B6B752D0732D40057A504 /* LogsViewController.swift in Sources */,
408C088E23155B34008C9667 /* WhatsNewHelper.swift in Sources */,
463538A726E16CD100BA9D35 /* Strings+L10n.swift in Sources */,
40043F0B23FBC6B1004A9B57 /* SiriPodcastItem.swift in Sources */,
4084263E2138E2750076D82E /* FeaturedCollectionViewCell.swift in Sources */,
46CD3CA12715E3E600F5EB8F /* SupportConfig.swift in Sources */,
BD5E8D41206211E300C84B43 /* OpmlImporter.swift in Sources */,
Expand All @@ -7282,7 +7267,6 @@
BDD71CF41BA935E8006D2CE3 /* NetworkViewController.swift in Sources */,
FF2142D42C07369200672D8D /* MediaExporter.swift in Sources */,
109446762CEB3A8100977161 /* CancelSubscriptionViewModel.swift in Sources */,
BD44A4452302DAC6004F55B2 /* CommonUpNextItem.swift in Sources */,
100C99552CE7B801008D73E9 /* CancelSubscriptionView.swift in Sources */,
BDA2065D1BB3AF5D00D38389 /* DownloadProgress.swift in Sources */,
407083C625423F0A002FC9F8 /* EpisodePreviewCell.swift in Sources */,
Expand Down
11 changes: 0 additions & 11 deletions podcasts/CommonUpNextItem.swift

This file was deleted.

4 changes: 0 additions & 4 deletions podcasts/SiriPodcastItem.swift

This file was deleted.

1 change: 1 addition & 0 deletions podcasts/SiriShortcutsManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Foundation
import Intents
import PocketCastsDataModel
import PocketCastsServer
import PocketCastsSharedModels
import PocketCastsUtils

class SiriShortcutsManager: CustomObserver {
Expand Down
1 change: 1 addition & 0 deletions podcasts/WidgetHelper.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

import PocketCastsDataModel
import PocketCastsServer
import PocketCastsSharedModels
import PocketCastsUtils
import WidgetKit

Expand Down