Skip to content

Commit 76dd257

Browse files
authored
Merge pull request #1 from Take111/feature/create_base
create client
2 parents a144ed9 + 7e5ca94 commit 76dd257

14 files changed

Lines changed: 876 additions & 0 deletions

File tree

.github/workflows/main.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: main
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
9+
jobs:
10+
build:
11+
runs-on: macos-latest
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v2
15+
- name: Build
16+
run: swift build -v
17+
test:
18+
runs-on: macos-latest
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v2
22+
- name: Test
23+
run: swift test -v

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEDidComputeMac32BitWarning</key>
6+
<true/>
7+
</dict>
8+
</plist>

Package.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// swift-tools-version: 5.10
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "WorldTimeAPIiOS",
8+
platforms: [
9+
.iOS(.v16),
10+
.tvOS(.v16),
11+
.macOS(.v12)
12+
],
13+
products: [
14+
// Products define the executables and libraries a package produces, making them visible to other packages.
15+
.library(
16+
name: "WorldTimeAPIiOS",
17+
targets: ["WorldTimeAPIiOS"]),
18+
],
19+
targets: [
20+
// Targets are the basic building blocks of a package, defining a module or a test suite.
21+
// Targets can depend on other targets in this package and products from dependencies.
22+
.target(
23+
name: "WorldTimeAPIiOS"),
24+
.testTarget(
25+
name: "WorldTimeAPIiOSTests",
26+
dependencies: ["WorldTimeAPIiOS"]),
27+
]
28+
)

README.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,79 @@
11
# WorldTimeAPI-ios
2+
3+
[![main](https://github.com/Take111/WorldTimeAPI-ios/actions/workflows/main.yml/badge.svg)](https://github.com/Take111/WorldTimeAPI-ios/actions/workflows/main.yml)
4+
5+
WorldTimeAPI-ios is a Swift package that provides a convenient way to interact with the WorldTime API. It allows iOS developers to easily fetch current time information for various timezones in their applications.
6+
7+
> [!NOTE]
8+
> WorldTimeAPI-ios utilizes the WorldTime API. For detailed information and documentation about the WorldTime API, please refer to the following link:
9+
[WorldTime API Documentation](http://worldtimeapi.org/)
10+
11+
## Installation
12+
13+
### Swift Package Manager
14+
15+
You can add WorldTimeAPI-ios to your project using Swift Package Manager. In Xcode, go to File > Swift Packages > Add Package Dependency and enter the repository URL:
16+
17+
```
18+
https://github.com/Take111/WorldTimeAPI-ios.git
19+
```
20+
21+
Alternatively, you can add it to your `Package.swift` file:
22+
23+
```swift
24+
dependencies: [
25+
.package(url: "https://github.com/Take111/WorldTimeAPI-ios.git", from: "0.1.0")
26+
]
27+
```
28+
29+
## How to Use
30+
31+
Here's a quick example of how to use WorldTimeAPI-ios in your project:
32+
33+
```swift
34+
import WorldTimeAPIiOS
35+
36+
let client = WorldTimeClient()
37+
38+
// Fetch current time for a specific timezone
39+
do {
40+
let currentTime = try await client.fetchCurrentTime(with: .etc(.utc))
41+
print("Current UTC time: \(currentTime.datetime)")
42+
} catch {
43+
print("Error fetching time: \(error)")
44+
}
45+
46+
// Fetch current UTC time as a TimeInterval
47+
do {
48+
if let timeInterval = try await client.fetchUTCDateTimeInterval() {
49+
print("Current UTC time interval: \(timeInterval)")
50+
}
51+
} catch {
52+
print("Error fetching UTC time interval: \(error)")
53+
}
54+
55+
// Fetch current UTC time as a Date
56+
do {
57+
if let date = try await client.fetchUTCDateTime() {
58+
print("Current UTC date: \(date)")
59+
}
60+
} catch {
61+
print("Error fetching UTC date: \(error)")
62+
}
63+
```
64+
65+
## Contribution
66+
67+
Contributions to WorldTimeAPI-ios are welcome! Here's how you can contribute:
68+
69+
1. Fork the repository
70+
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
71+
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
72+
4. Push to the branch (`git push origin feature/AmazingFeature`)
73+
5. Open a Pull Request
74+
75+
Please make sure to update tests as appropriate and adhere to the project's coding style.
76+
77+
## License
78+
79+
This project is licensed under the MIT License. However, please note that the API used in this project belongs to WorldTimeAPI. Be sure to check the WorldTimeAPI's terms and conditions for usage of their API.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// APIClient.swift
3+
//
4+
//
5+
// Created by 竹ノ内愛斗 on 2024/08/03.
6+
//
7+
8+
import Foundation
9+
10+
11+
enum APIClientError: Error {
12+
case invalidURL
13+
case invalidResponse
14+
}
15+
16+
protocol APIClient {
17+
func request<T>(_ entity: T) async throws -> T.ResponseEntity where T: APIRequest
18+
}
19+
20+
final class APIClientImpl: APIClient {
21+
func request<T>(_ entity: T) async throws -> T.ResponseEntity where T: APIRequest {
22+
let url = entity.url
23+
let components = URLComponents(url: url, resolvingAgainstBaseURL: true)
24+
25+
guard let requestURL = components?.url else {
26+
throw APIClientError.invalidURL
27+
}
28+
29+
let (data, urlResponse) = try await URLSession.shared.data(from: requestURL)
30+
guard let response = urlResponse as? HTTPURLResponse, response.statusCode == 200 else {
31+
throw APIClientError.invalidResponse
32+
}
33+
return try JSONDecoder().decode(T.ResponseEntity.self, from: data)
34+
}
35+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// String+Extension.swift
3+
//
4+
//
5+
// Created by 竹ノ内愛斗 on 2024/08/03.
6+
//
7+
8+
import Foundation
9+
10+
extension String {
11+
var toTimeInterval: TimeInterval? {
12+
let formatter = ISO8601DateFormatter()
13+
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
14+
return formatter.date(from: self)?.timeIntervalSince1970
15+
}
16+
17+
var toDate: Date? {
18+
let formatter = ISO8601DateFormatter()
19+
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
20+
return formatter.date(from: self)
21+
}
22+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// APIRequest.swift
3+
//
4+
//
5+
// Created by 竹ノ内愛斗 on 2024/08/03.
6+
//
7+
8+
import Foundation
9+
10+
protocol APIRequest {
11+
associatedtype ResponseEntity: Decodable
12+
13+
var url: URL { get }
14+
}
15+
16+
enum WorldTimeAPIRequest {
17+
18+
static let baseURL = URL(string: "https://worldtimeapi.org/api")!
19+
20+
struct CurrentTimeWithTimeZoneRequest: APIRequest {
21+
typealias ResponseEntity = CurrentTimeWithTimeZone
22+
23+
let timezone: TimeZone
24+
25+
var url: URL {
26+
baseURL.appendingPathComponent("timezone")
27+
.appendingPathComponent(timezone.stringValue)
28+
}
29+
}
30+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//
2+
// CurrentTimeWithTimeZone.swift
3+
//
4+
//
5+
// Created by 竹ノ内愛斗 on 2024/08/03.
6+
//
7+
8+
import Foundation
9+
10+
public struct CurrentTimeWithTimeZone: Decodable {
11+
let abbreviation: String
12+
let clientIP: String
13+
let datetime: String
14+
let dayOfWeek: Int
15+
let dayOfYear: Int
16+
let dst: Bool
17+
let dstFrom: String?
18+
let dstOffset: Int
19+
let dstUntil: String?
20+
let rawOffset: Int
21+
let timezone: String
22+
let unixtime: Int
23+
let utcDatetime: String
24+
let utcOffset: String
25+
let weekNumber: Int
26+
27+
enum CodingKeys: String, CodingKey {
28+
case abbreviation
29+
case clientIP = "client_ip"
30+
case datetime
31+
case dayOfWeek = "day_of_week"
32+
case dayOfYear = "day_of_year"
33+
case dst
34+
case dstFrom = "dst_from"
35+
case dstOffset = "dst_offset"
36+
case dstUntil = "dst_until"
37+
case rawOffset = "raw_offset"
38+
case timezone
39+
case unixtime
40+
case utcDatetime = "utc_datetime"
41+
case utcOffset = "utc_offset"
42+
case weekNumber = "week_number"
43+
}
44+
}

0 commit comments

Comments
 (0)