Skip to content
This repository has been archived by the owner on May 2, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1 from KU-Stacks/release/sputnik/1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaesung committed Apr 22, 2023
2 parents ebe10b4 + ea59833 commit 8025495
Show file tree
Hide file tree
Showing 12 changed files with 473 additions and 129 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/build_package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: The Satellite Swift Package Build

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
name: Build package
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
swift-version: "5.7.0"
- name: Building...
run: |
xcodebuild build -scheme Satellite -destination 'platform=iOS Simulator,name=iPhone 14 Pro,OS=latest'
34 changes: 34 additions & 0 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: The Satellite Documentation

on:
push:
branches: [ main ]

jobs:
deploy:
environment:
# Must be set to this for deploying to GitHub Pages
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: macos-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v3
- name: Build DocC
run: |
xcodebuild docbuild -scheme Satellite \
-derivedDataPath /tmp/docbuild \
-destination 'generic/platform=iOS';
$(xcrun --find docc) process-archive \
transform-for-static-hosting /tmp/docbuild/Build/Products/Debug-iphoneos/Satellite.doccarchive \
--hosting-base-path TheSatellite \
--output-path docs;
echo "<script>window.location.href += \"/documentation/Satellite\"</script>" > docs/index.html;
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
# Upload only docs directory
path: 'docs'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
21 changes: 21 additions & 0 deletions .github/workflows/unit_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: The Satellite Unit Tests

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
name: Run unit tests in SatelliteTests
runs-on: macos-latest

steps:
- name: Checkout
uses: actions/checkout@v3
with:
swift-version: "5.7.0"
- name: Testing...
run: |
xcodebuild clean test -scheme Satellite -destination 'platform=iOS Simulator,name=iPhone 14 Pro,OS=latest'
95 changes: 7 additions & 88 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,90 +1,9 @@
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## User settings
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/

## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout

## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3

## Obj-C/Swift specific
*.hmap

## App packaging
*.ipa
*.dSYM.zip
*.dSYM

## Playgrounds
timeline.xctimeline
playground.xcworkspace

# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm

.build/

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build/

# Accio dependency management
Dependencies/
.accio/

# fastlane
#
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output

# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode

iOSInjectionProject/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http:https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
30 changes: 30 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "Satellite",
platforms: [.iOS(.v15)],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "Satellite",
targets: ["Satellite"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "Satellite",
dependencies: []),
.testTarget(
name: "SatelliteTests",
dependencies: ["Satellite"]),
]
)
78 changes: 37 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,58 @@ The Satellite is an API communication module written in Swift.

## v1: Sputnik

"Version **Sputnik**" is the very first version of **The Satellite**, providing very basic public interfaces for API communication in Swift. It offers two main interfaces, one for *Swift concurrency* and another for *Combine*. Let's see how to use them.

### Setting up with API key and your domain
```swift
Satellite.setup(
let satellite = Satellite(
host: "{BASE.URL}",
scheme: .https, // default: .https
key: "{API.KEY}" // default: nil
scheme: .http // default: `.https`
)
```

### Declare Request and Response
```swift
struct Feedback: Codable {
let id: String
let content: String
}

struct FeedbackRequest: Request {
associatedType RequestType = FeedbackResponse.self

let version = .version("v1")
let httpMethod = .get
let path = "feedback"
let queryItems: [URLQueryItem]?

// MARK: Data (HTTP body)
let feedback: Feedback

init(feedback: Feedback) {
self.feedback = feedback
}

func urlRequest(for host: String, scheme: URLScheme) throws -> URLRequest {
guard let components = URLComponents(string: "\(scheme.rawValue):https://\(host)/\(path)" else {
throw Satellite.NetworkError.urlIsInvalid
}
if let queryItems {
components.queryItems = queryItems
}
var urlRequest = URLRequest(url: components.url)
urlRequest.headers = ["Content-Type: "application/json"]
urlRequest.httpMethod = httpMethod.description
urlRequest.httpBody = try JSONEncoder().encode(feedback)
urlRequest.timeoutInterval = 5.0\
return urlRequest
}
// Expected response object
struct CatFact: Codable {
let text: String
}
```

### Sending the request and receiving the response (Combine/Publisher)
```swift
let cancellable = Satellite
.send(request)
.responsePublisher()
let satellite = Satellite(host: "cat-fact.herokuapp.com")
cancellable = statellite
.responsePublisher<ResponseType: [CatFact]>(
for: "facts/random",
httpMethod: .get,
queryItems: [
URLQueryItem(name: "animal_type", value: "cat"),
URLQueryItem(name: "amount", value: "2")
]
)
.sink(
receiveCompletion: { print ("Received completion: \($0).") },
receiveValue: { catFacts in print("Cat Facts: \(catFacts).")}
)
```

> **INFORMATION** For the more information on URLSession data task publisher, please see this [link](https://developer.apple.com/documentation/foundation/urlsession/processing_url_session_data_task_results_with_combine)
### Sending the request and waiting the response (Async await)
```swift
let response = try await Satellite.response(from: request)
let satellite = Satellite(host: "cat-fact.herokuapp.com")
let catFacts: [CatFact] = try await satellite.response(
for: "facts/random",
httpMethod: .get,
queryItems: [
URLQueryItem(name: "animal_type", value: "cat"),
URLQueryItem(name: "amount", value: "2")
]
)
self.text = catFacts
.compactMap { $0.text }
.joined(separator: ", ")
```

> **INFORMATION** For the more information on using async/await style, please see this [link](https://developer.apple.com/documentation/swift/updating_an_app_to_use_swift_concurrency)
55 changes: 55 additions & 0 deletions Sources/Satellite/Satellite.Error.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Satellite.Error.swift
//
//
// Created by Jaesung Lee on 2023/04/14.
//
/**
MIT License
Copyright (c) 2023 Kuring
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

import Foundation

extension Satellite {
/// The enumeration that defines error cases used in ``Satellite``
public enum Error: Swift.Error, CustomStringConvertible {
case urlIsInvalid
case requestIsInvalid
case requestIsFailed
case responseHasNoData
case responseIsFailedDecoding
case statusCode(_ statusCode: Int)

/// The description of the error
public var description: String {
switch self {
case .urlIsInvalid: return "URL is invalid"
case .requestIsInvalid: return "URL request is invalid"
case .requestIsFailed: return "Request is failed"
case .responseHasNoData: return "Response has no data"
case .responseIsFailedDecoding: return "Response is failed decoding"
case .statusCode(let code): return "Status code: \(code)"
}
}
}
}
Loading

0 comments on commit 8025495

Please sign in to comment.