Add first bit of network functionality
This commit is contained in:
parent
9ec81b4ee0
commit
36a58874e0
@ -6,6 +6,10 @@
|
|||||||
objectVersion = 77;
|
objectVersion = 77;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
C3A5E8D52ED0C60D002DB10E /* Meow in Frameworks */ = {isa = PBXBuildFile; productRef = C3A5E8D42ED0C60D002DB10E /* Meow */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
C3BB76492ED0C38900D56534 /* PBXContainerItemProxy */ = {
|
C3BB76492ED0C38900D56534 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
@ -24,15 +28,16 @@
|
|||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
C3A5E8D22ED0C5E8002DB10E /* Meow */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Meow; sourceTree = "<group>"; };
|
||||||
C3BB763B2ED0C38800D56534 /* Meow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Meow.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
C3BB763B2ED0C38800D56534 /* Meow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Meow.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
C3BB76482ED0C38900D56534 /* MeowTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MeowTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
C3BB76482ED0C38900D56534 /* MeowTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MeowTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
C3BB76522ED0C38900D56534 /* MeowUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MeowUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
C3BB76522ED0C38900D56534 /* MeowUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MeowUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||||
C3BB763D2ED0C38800D56534 /* Meow */ = {
|
C3BB763D2ED0C38800D56534 /* App */ = {
|
||||||
isa = PBXFileSystemSynchronizedRootGroup;
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
path = Meow;
|
path = App;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C3BB764B2ED0C38900D56534 /* MeowTests */ = {
|
C3BB764B2ED0C38900D56534 /* MeowTests */ = {
|
||||||
@ -52,6 +57,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
C3A5E8D52ED0C60D002DB10E /* Meow in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -75,7 +81,8 @@
|
|||||||
C3BB76322ED0C38800D56534 = {
|
C3BB76322ED0C38800D56534 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C3BB763D2ED0C38800D56534 /* Meow */,
|
C3A5E8D22ED0C5E8002DB10E /* Meow */,
|
||||||
|
C3BB763D2ED0C38800D56534 /* App */,
|
||||||
C3BB764B2ED0C38900D56534 /* MeowTests */,
|
C3BB764B2ED0C38900D56534 /* MeowTests */,
|
||||||
C3BB76552ED0C38900D56534 /* MeowUITests */,
|
C3BB76552ED0C38900D56534 /* MeowUITests */,
|
||||||
C3BB763C2ED0C38800D56534 /* Products */,
|
C3BB763C2ED0C38800D56534 /* Products */,
|
||||||
@ -108,10 +115,11 @@
|
|||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
fileSystemSynchronizedGroups = (
|
fileSystemSynchronizedGroups = (
|
||||||
C3BB763D2ED0C38800D56534 /* Meow */,
|
C3BB763D2ED0C38800D56534 /* App */,
|
||||||
);
|
);
|
||||||
name = Meow;
|
name = Meow;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
|
C3A5E8D42ED0C60D002DB10E /* Meow */,
|
||||||
);
|
);
|
||||||
productName = Meow;
|
productName = Meow;
|
||||||
productReference = C3BB763B2ED0C38800D56534 /* Meow.app */;
|
productReference = C3BB763B2ED0C38800D56534 /* Meow.app */;
|
||||||
@ -578,6 +586,13 @@
|
|||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
C3A5E8D42ED0C60D002DB10E /* Meow */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = Meow;
|
||||||
|
};
|
||||||
|
/* End XCSwiftPackageProductDependency section */
|
||||||
};
|
};
|
||||||
rootObject = C3BB76332ED0C38800D56534 /* Project object */;
|
rootObject = C3BB76332ED0C38800D56534 /* Project object */;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
102
Meow.xcodeproj/xcshareddata/xcschemes/App.xcscheme
Normal file
102
Meow.xcodeproj/xcshareddata/xcschemes/App.xcscheme
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "2610"
|
||||||
|
version = "1.7">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES"
|
||||||
|
buildArchitectures = "Automatic">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "C3BB763A2ED0C38800D56534"
|
||||||
|
BuildableName = "Meow.app"
|
||||||
|
BlueprintName = "Meow"
|
||||||
|
ReferencedContainer = "container:Meow.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
shouldAutocreateTestPlan = "YES">
|
||||||
|
<Testables>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO"
|
||||||
|
parallelizable = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "C3BB76472ED0C38900D56534"
|
||||||
|
BuildableName = "MeowTests.xctest"
|
||||||
|
BlueprintName = "MeowTests"
|
||||||
|
ReferencedContainer = "container:Meow.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO"
|
||||||
|
parallelizable = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "C3BB76512ED0C38900D56534"
|
||||||
|
BuildableName = "MeowUITests.xctest"
|
||||||
|
BlueprintName = "MeowUITests"
|
||||||
|
ReferencedContainer = "container:Meow.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "C3BB763A2ED0C38800D56534"
|
||||||
|
BuildableName = "Meow.app"
|
||||||
|
BlueprintName = "Meow"
|
||||||
|
ReferencedContainer = "container:Meow.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "C3BB763A2ED0C38800D56534"
|
||||||
|
BuildableName = "Meow.app"
|
||||||
|
BlueprintName = "Meow"
|
||||||
|
ReferencedContainer = "container:Meow.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
@ -4,11 +4,29 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>SchemeUserState</key>
|
<key>SchemeUserState</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Meow.xcscheme_^#shared#^_</key>
|
<key>App.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>SuppressBuildableAutocreation</key>
|
||||||
|
<dict>
|
||||||
|
<key>C3BB763A2ED0C38800D56534</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>C3BB76472ED0C38900D56534</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>C3BB76512ED0C38900D56534</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
8
Meow/.gitignore
vendored
Normal file
8
Meow/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.DS_Store
|
||||||
|
/.build
|
||||||
|
/Packages
|
||||||
|
xcuserdata/
|
||||||
|
DerivedData/
|
||||||
|
.swiftpm/configuration/registries.json
|
||||||
|
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||||
|
.netrc
|
||||||
27
Meow/Package.swift
Normal file
27
Meow/Package.swift
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// swift-tools-version: 6.2
|
||||||
|
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||||
|
|
||||||
|
import PackageDescription
|
||||||
|
|
||||||
|
let package = Package(
|
||||||
|
name: "Meow",
|
||||||
|
platforms: [.iOS(.v18), .macOS(.v15)],
|
||||||
|
products: [
|
||||||
|
// Products define the executables and libraries a package produces, making them visible to other packages.
|
||||||
|
.library(
|
||||||
|
name: "Meow",
|
||||||
|
targets: ["Meow"]
|
||||||
|
),
|
||||||
|
],
|
||||||
|
targets: [
|
||||||
|
// Targets are the basic building blocks of a package, defining a module or a test suite.
|
||||||
|
// Targets can depend on other targets in this package and products from dependencies.
|
||||||
|
.target(
|
||||||
|
name: "Meow"
|
||||||
|
),
|
||||||
|
.testTarget(
|
||||||
|
name: "MeowTests",
|
||||||
|
dependencies: ["Meow"]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
10
Meow/Sources/Meow/FactsResponse.swift
Normal file
10
Meow/Sources/Meow/FactsResponse.swift
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
//
|
||||||
|
// FactsResponse.swift
|
||||||
|
// Meow
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct FactsResponse: Codable {
|
||||||
|
let data: [String]
|
||||||
|
}
|
||||||
43
Meow/Sources/Meow/Meow.swift
Normal file
43
Meow/Sources/Meow/Meow.swift
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// Meow.swift
|
||||||
|
// Meow
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public struct Meow {
|
||||||
|
let baseURL: URL
|
||||||
|
let session: URLSession
|
||||||
|
|
||||||
|
public init(baseURL: URL, session: URLSession = .shared) {
|
||||||
|
self.baseURL = baseURL
|
||||||
|
self.session = session
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getFacts() async throws -> [String] {
|
||||||
|
let request = try generateRequest(path: "/")
|
||||||
|
let response: FactsResponse = try await decodeRequest(request: request)
|
||||||
|
return response.data
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private functionality
|
||||||
|
|
||||||
|
private func generateRequest(path: String) throws -> URLRequest {
|
||||||
|
guard let url = URL(string: path, relativeTo: baseURL) else {
|
||||||
|
throw MeowError.requestError("Couldn't generate URL from path: \(path), baseURL: \(baseURL)")
|
||||||
|
}
|
||||||
|
return URLRequest(url: url)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func decodeRequest<T: Decodable>(request: URLRequest) async throws -> T {
|
||||||
|
let (data, response) = try await session.data(for: request)
|
||||||
|
guard let response = response as? HTTPURLResponse else {
|
||||||
|
throw MeowError.connectionError("Couldn't get HTTP response from request \(request)")
|
||||||
|
}
|
||||||
|
guard response.statusCode < 300 else {
|
||||||
|
let body = String(data: data, encoding: .utf8)
|
||||||
|
throw MeowError.responseError(response.statusCode, body ?? "unknown error")
|
||||||
|
}
|
||||||
|
return try JSONDecoder().decode(T.self, from: data)
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Meow/Sources/Meow/MeowError.swift
Normal file
12
Meow/Sources/Meow/MeowError.swift
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
//
|
||||||
|
// MeowError.swift
|
||||||
|
// Meow
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public enum MeowError: LocalizedError {
|
||||||
|
case requestError(String)
|
||||||
|
case connectionError(String)
|
||||||
|
case responseError(Int, String)
|
||||||
|
}
|
||||||
19
Meow/Tests/MeowTests/MeowTests.swift
Normal file
19
Meow/Tests/MeowTests/MeowTests.swift
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// MeowTests.swift
|
||||||
|
// MeowTests
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
@testable import Meow
|
||||||
|
|
||||||
|
@Suite("Meow Tests")
|
||||||
|
struct MeowTests {
|
||||||
|
private let baseURL = URL(string: "https://meow.meow")!
|
||||||
|
|
||||||
|
@Test
|
||||||
|
func constructor() async throws {
|
||||||
|
let instance = Meow(baseURL: baseURL)
|
||||||
|
#expect(instance.baseURL == baseURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user