Skip to content

Commit b5992f0

Browse files
committed
basic readme
1 parent fbdefb1 commit b5992f0

File tree

1 file changed

+26
-179
lines changed

1 file changed

+26
-179
lines changed

README.md

Lines changed: 26 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -1,218 +1,65 @@
11
# SwiftHttp
22

3-
An awesome Swift HTTP library to rapidly setup the communication layer with API endpoints.
4-
5-
```swift
6-
import SwiftHttp
7-
8-
print(html)
9-
```
10-
3+
An awesome Swift HTTP library to rapidly create communication layers with API endpoints.
114

125
## Install
136

147
You can simply use `SwiftHtml` as a dependency via the Swift Package Manager:
158

169
```swift
17-
.package(url: "https://github.com/binarybirds/swift-html", from: "1.6.0"),
10+
.package(url: "https://github.com/binarybirds/swift-http", from: "1.0.0"),
1811
```
1912

20-
Add the `SwiftHtml` product from the `swift-html` package as a dependency to your target:
13+
Add the `SwiftHttp` product from the `swift-http` package as a dependency to your target:
2114

2215
```swift
23-
.product(name: "SwiftHtml", package: "swift-html"),
16+
.product(name: "SwiftHttp", package: "swift-http"),
2417
```
2518

2619
Import the framework:
2720

2821
```swift
29-
import SwiftHtml
22+
import SwiftHttp
3023
```
3124

3225
That's it.
3326

3427

35-
## Creating custom tags
36-
37-
You can define your own custom tags by subclassing the `Tag` or `EmptyTag` class.
38-
39-
You can follow the same pattern if you take a look at the core tags.
40-
41-
```swift
42-
open class Div: Tag {
43-
44-
}
45-
46-
// <div></div> - standard tag
47-
48-
open class Br: EmptyTag {
49-
50-
}
51-
// <br> - no closing tag
52-
53-
```
54-
55-
By default the name of the tag is automatically derived from the class name (lowercased), but you can also create your own tag type & name by overriding the `createNode()` class function.
56-
57-
```swift
58-
open class LastBuildDate: Tag {
59-
60-
open override class func createNode() -> Node {
61-
Node(type: .standard, name: "lastBuildDate")
62-
}
63-
}
64-
65-
// <lastBuildDate></lastBuildDate> - standard tag with custom name
66-
```
67-
68-
It is also possible to create tags with altered content or default attributes.
69-
70-
```swift
71-
open class Description: Tag {
72-
73-
public init(_ contents: String) {
74-
super.init()
75-
setContents("<![CDATA[" + contents + "]]>")
76-
}
77-
}
78-
// <description><![CDATA[lorem ipsum]]></description> - content wrapped in CDATA
79-
80-
open class Rss: Tag {
81-
82-
public init(@TagBuilder _ builder: () -> [Tag]) {
83-
super.init(builder())
84-
setAttributes([
85-
.init(key: "version", value: "2.0"),
86-
])
87-
}
88-
}
89-
// <rss version="2.0">...</rss> - tag with a default attribute
90-
```
91-
92-
## Attribute management
28+
## Basic usage
9329

94-
You can set, add or delete the attributes of a given tag.
30+
It is really easy to setup a communication layer with an API endpoint.
9531

9632
```swift
97-
Leaf("example")
98-
// set (override) the current attributes
99-
.setAttributes([
100-
.init(key: "a", value: "foo"),
101-
.init(key: "b", value: "bar"),
102-
.init(key: "c", value: "baz"),
103-
])
104-
// add a new attribute using a key & value
105-
.attribute("foo", "example")
106-
// add a new flag attribute (without a value)
107-
.flagAttribute("bar")
108-
// delete an attribute by using a key
109-
.deleteAttribute("b")
110-
111-
// <leaf a="foo" c="baz" foo="example" bar></leaf>
112-
```
113-
114-
You can also manage the class atrribute through helper methods.
115-
116-
```swift
117-
Span("foo")
118-
// set (override) class values
119-
.class("a", "b", "c")
120-
// add new class values
121-
.class(add: ["d", "e", "f"])
122-
// add new class value if the condition is true
123-
.class(add: "b", true)
124-
/// remove multiple class values
125-
.class(remove: ["b", "c", "d"])
126-
/// remove a class value if the condition is true
127-
.class(remove: "e", true)
128-
129-
// <span class="a f"></span>
130-
```
131-
132-
You can create your own attribute modifier via an extension.
133-
134-
```swift
135-
public extension Guid {
136-
137-
func isPermalink(_ value: Bool = true) -> Self {
138-
attribute("isPermalink", String(value))
139-
}
140-
}
141-
```
142-
143-
There are other built-in type-safe attribute modifiers available on tags.
144-
145-
146-
## Composing tags
147-
148-
You can come up with your own `Tag` composition system by introducing a new protocol.
149-
150-
```swift
151-
protocol TagRepresentable {
152-
153-
func build() -> Tag
154-
}
155-
156-
struct ListComponent: TagRepresentable {
33+
import SwiftHttp
15734

158-
let items: [String]
159-
160-
init(_ items: [String]) {
161-
self.items = items
162-
}
163-
164-
@TagBuilder
165-
func build() -> Tag {
166-
Ul {
167-
items.map { Li($0) }
168-
}
169-
}
35+
struct Todo: Codable {
36+
let id: Int
37+
let title: String
38+
let completed: Bool
17039
}
17140

172-
let tag = ListComponent(["a", "b", "c"]).build()
173-
```
174-
175-
This way it is also possible to extend the `TagBuilder` to support the new protocol.
41+
struct TodoApi: HttpCodablePipelineCollection {
17642

177-
```swift
178-
extension TagBuilder {
43+
let client: HttpClient = UrlSessionHttpClient(log: true)
44+
let apiBaseUrl = HttpUrl(host: "jsonplaceholder.typicode.com")
17945

180-
static func buildExpression(_ expression: TagRepresentable) -> Tag {
181-
expression.build()
182-
}
18346

184-
static func buildExpression(_ expression: TagRepresentable) -> [Tag] {
185-
[expression.build()]
186-
}
187-
188-
static func buildExpression(_ expression: [TagRepresentable]) -> [Tag] {
189-
expression.map { $0.build() }
190-
}
191-
192-
static func buildExpression(_ expression: [TagRepresentable]) -> Tag {
193-
GroupTag {
194-
expression.map { $0.build() }
195-
}
196-
}
47+
func list() async throws -> [Todo] {
48+
try await decodableRequest(executor: client.dataTask,
49+
url: apiBaseUrl.path("todos"),
50+
method: .get)
51+
}
19752
}
198-
```
19953

200-
Sometimes you'll need extra parameters for the build function, so you have to call the build method by hand.
54+
// api usage
55+
let todos = try await api.list()
20156

202-
In those cases it is recommended to introduce a `render` function instead of using build.
57+
// curl log
58+
// curl "https://jsonplaceholder.typicode.com/todos/"
20359

204-
```swift
205-
206-
let tag = WebIndexTemplate(ctx) {
207-
ListComponent(["a", "b", "c"])
208-
.render(req)
209-
}
210-
.render(req)
21160
```
21261

213-
If you want to create a lightweight template engine for the [Vapor](https://vapor.codes/) web framework using SwiftHtml, you can see a working example inside the [Feather CMS core](https://github.com/FeatherCMS/feather-core) repository.
214-
62+
The HttpClient provides the executors to perform data, download or upload tasks.
21563

216-
## Credits & references
64+
You can create decodable, encodable, codable or raw request when using a codable pipeline collection.
21765

218-
- [HTML Reference](https://www.w3schools.com/tags/default.asp)

0 commit comments

Comments
 (0)