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

Commit c1d3b5f

Browse files
committed
Merge pull request #10 from WeltN24/mutations
Mutations - closes #9
2 parents f6807fa + e718d56 commit c1d3b5f

18 files changed

+419
-221
lines changed

GraphQLicious.xcodeproj/project.pbxproj

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
D82417671CF5F404002F7B91 /* QueryType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D82417661CF5F404002F7B91 /* QueryType.swift */; };
11+
D82417691CF6F256002F7B91 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = D82417681CF6F256002F7B91 /* Request.swift */; };
12+
D824176B1CF6F474002F7B91 /* MutatingRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D824176A1CF6F474002F7B91 /* MutatingRequest.swift */; };
13+
D824176D1CF6F8B6002F7B91 /* Mutation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D824176C1CF6F8B6002F7B91 /* Mutation.swift */; };
14+
D824176F1CF6F9A0002F7B91 /* Operation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D824176E1CF6F9A0002F7B91 /* Operation.swift */; };
1015
D843F2291CBD1FFC00F73BF2 /* GraphQLicious.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D86C60491CAC20AE002691B9 /* GraphQLicious.framework */; };
1116
D843F22A1CBD1FFC00F73BF2 /* GraphQLicious.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D86C60491CAC20AE002691B9 /* GraphQLicious.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1217
D843F22E1CBD20A400F73BF2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D86C606B1CAC20DA002691B9 /* ViewController.swift */; };
1318
D843F22F1CBD20AB00F73BF2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D86C60691CAC20DA002691B9 /* AppDelegate.swift */; };
1419
D8681D321CB661240090627B /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8681D311CB661240090627B /* String.swift */; };
1520
D8681D341CB672F60090627B /* Fragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8681D331CB672F60090627B /* Fragment.swift */; };
16-
D8681D381CB69DFA0090627B /* Int.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8681D371CB69DFA0090627B /* Int.swift */; };
17-
D8681D3A1CB69E090090627B /* Float.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8681D391CB69E090090627B /* Float.swift */; };
18-
D8681D3C1CB69E1A0090627B /* Double.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8681D3B1CB69E1A0090627B /* Double.swift */; };
1921
D8681D3E1CB69E380090627B /* SequenceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8681D3D1CB69E380090627B /* SequenceType.swift */; };
2022
D8681D411CB69FFE0090627B /* ArgumentValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8681D401CB69FFE0090627B /* ArgumentValue.swift */; };
2123
D8681D431CB6A4F70090627B /* GraphQLConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8681D421CB6A4F70090627B /* GraphQLConvertible.swift */; };
@@ -26,7 +28,7 @@
2628
D86C606F1CAC20DA002691B9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D86C606D1CAC20DA002691B9 /* Main.storyboard */; };
2729
D86C60711CAC20DA002691B9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D86C60701CAC20DA002691B9 /* Assets.xcassets */; };
2830
D86C60741CAC20DA002691B9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D86C60721CAC20DA002691B9 /* LaunchScreen.storyboard */; };
29-
D86C607A1CAC2251002691B9 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = D86C60791CAC2251002691B9 /* Request.swift */; };
31+
D86C607A1CAC2251002691B9 /* ReadingRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D86C60791CAC2251002691B9 /* ReadingRequest.swift */; };
3032
D8713B441CAD4367000AD793 /* Argument.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8713B431CAD4367000AD793 /* Argument.swift */; };
3133
D8713B461CAE67C3000AD793 /* QueryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8713B451CAE67C3000AD793 /* QueryTests.swift */; };
3234
D8B36A3C1CAEA0CF00D4A18B /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B36A3B1CAEA0CF00D4A18B /* Query.swift */; };
@@ -65,11 +67,13 @@
6567
/* End PBXCopyFilesBuildPhase section */
6668

6769
/* Begin PBXFileReference section */
70+
D82417661CF5F404002F7B91 /* QueryType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryType.swift; sourceTree = "<group>"; };
71+
D82417681CF6F256002F7B91 /* Request.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Request.swift; sourceTree = "<group>"; };
72+
D824176A1CF6F474002F7B91 /* MutatingRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MutatingRequest.swift; sourceTree = "<group>"; };
73+
D824176C1CF6F8B6002F7B91 /* Mutation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Mutation.swift; sourceTree = "<group>"; };
74+
D824176E1CF6F9A0002F7B91 /* Operation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operation.swift; sourceTree = "<group>"; };
6875
D8681D311CB661240090627B /* String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
6976
D8681D331CB672F60090627B /* Fragment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fragment.swift; sourceTree = "<group>"; };
70-
D8681D371CB69DFA0090627B /* Int.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Int.swift; sourceTree = "<group>"; };
71-
D8681D391CB69E090090627B /* Float.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Float.swift; sourceTree = "<group>"; };
72-
D8681D3B1CB69E1A0090627B /* Double.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Double.swift; sourceTree = "<group>"; };
7377
D8681D3D1CB69E380090627B /* SequenceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SequenceType.swift; sourceTree = "<group>"; };
7478
D8681D401CB69FFE0090627B /* ArgumentValue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArgumentValue.swift; sourceTree = "<group>"; };
7579
D8681D421CB6A4F70090627B /* GraphQLConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphQLConvertible.swift; sourceTree = "<group>"; };
@@ -87,7 +91,7 @@
8791
D86C60701CAC20DA002691B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
8892
D86C60731CAC20DA002691B9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
8993
D86C60751CAC20DA002691B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
90-
D86C60791CAC2251002691B9 /* Request.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Request.swift; sourceTree = "<group>"; };
94+
D86C60791CAC2251002691B9 /* ReadingRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadingRequest.swift; sourceTree = "<group>"; };
9195
D8713B431CAD4367000AD793 /* Argument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Argument.swift; sourceTree = "<group>"; };
9296
D8713B451CAE67C3000AD793 /* QueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryTests.swift; sourceTree = "<group>"; };
9397
D8B36A3B1CAEA0CF00D4A18B /* Query.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Query.swift; sourceTree = "<group>"; };
@@ -125,10 +129,8 @@
125129
isa = PBXGroup;
126130
children = (
127131
D8681D311CB661240090627B /* String.swift */,
128-
D8681D371CB69DFA0090627B /* Int.swift */,
129-
D8681D391CB69E090090627B /* Float.swift */,
130-
D8681D3B1CB69E1A0090627B /* Double.swift */,
131132
D8681D3D1CB69E380090627B /* SequenceType.swift */,
133+
D82417661CF5F404002F7B91 /* QueryType.swift */,
132134
);
133135
path = Helper;
134136
sourceTree = "<group>";
@@ -139,6 +141,8 @@
139141
D8E6F92C1CAD27C000FF7966 /* Field.swift */,
140142
D8681D401CB69FFE0090627B /* ArgumentValue.swift */,
141143
D8681D421CB6A4F70090627B /* GraphQLConvertible.swift */,
144+
D82417681CF6F256002F7B91 /* Request.swift */,
145+
D824176E1CF6F9A0002F7B91 /* Operation.swift */,
142146
);
143147
path = Interfaces;
144148
sourceTree = "<group>";
@@ -170,9 +174,11 @@
170174
D8681D3F1CB69F070090627B /* Interfaces */,
171175
D86C604C1CAC20AE002691B9 /* GraphQLicious.h */,
172176
D86C604E1CAC20AE002691B9 /* Info.plist */,
173-
D86C60791CAC2251002691B9 /* Request.swift */,
177+
D86C60791CAC2251002691B9 /* ReadingRequest.swift */,
178+
D824176A1CF6F474002F7B91 /* MutatingRequest.swift */,
174179
D8681D331CB672F60090627B /* Fragment.swift */,
175180
D8B36A3B1CAEA0CF00D4A18B /* Query.swift */,
181+
D824176C1CF6F8B6002F7B91 /* Mutation.swift */,
176182
D8713B431CAD4367000AD793 /* Argument.swift */,
177183
);
178184
path = Sources;
@@ -344,15 +350,17 @@
344350
isa = PBXSourcesBuildPhase;
345351
buildActionMask = 2147483647;
346352
files = (
353+
D824176D1CF6F8B6002F7B91 /* Mutation.swift in Sources */,
354+
D824176F1CF6F9A0002F7B91 /* Operation.swift in Sources */,
347355
D8681D321CB661240090627B /* String.swift in Sources */,
348356
D8713B441CAD4367000AD793 /* Argument.swift in Sources */,
357+
D82417671CF5F404002F7B91 /* QueryType.swift in Sources */,
349358
D8E6F92D1CAD27C000FF7966 /* Field.swift in Sources */,
359+
D82417691CF6F256002F7B91 /* Request.swift in Sources */,
350360
D8681D341CB672F60090627B /* Fragment.swift in Sources */,
351-
D8681D3A1CB69E090090627B /* Float.swift in Sources */,
352-
D8681D381CB69DFA0090627B /* Int.swift in Sources */,
361+
D824176B1CF6F474002F7B91 /* MutatingRequest.swift in Sources */,
353362
D8681D3E1CB69E380090627B /* SequenceType.swift in Sources */,
354-
D86C607A1CAC2251002691B9 /* Request.swift in Sources */,
355-
D8681D3C1CB69E1A0090627B /* Double.swift in Sources */,
363+
D86C607A1CAC2251002691B9 /* ReadingRequest.swift in Sources */,
356364
D8681D411CB69FFE0090627B /* ArgumentValue.swift in Sources */,
357365
D8681D431CB6A4F70090627B /* GraphQLConvertible.swift in Sources */,
358366
D8B36A3C1CAEA0CF00D4A18B /* Query.swift in Sources */,

README.md

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ You can directly drag and drop the needed files into your project, but keep in m
4444
The files are contained in the `Sources` folder and work for the `iOS` framework
4545

4646
## Usage
47+
### Query
4748
Let's assume, we have the id of an article and we want to have the `headline`, `body` text and `opener image` of that article.
4849

4950
Our graphQL query for that will look like this:
5051

5152
```graphQL
52-
{
53+
query {
5354
test: content(id: 153082687){
5455
...contentFields
5556
}
@@ -63,7 +64,7 @@ fragment contentFields on Content {
6364
}
6465
fragment imageContent on Image {
6566
id
66-
...urlFragment
67+
url
6768
}
6869
fragment urlFragment on Image {
6970
url (ratio: 1, size: 200)
@@ -108,7 +109,7 @@ let customEnumArgument = Argument(
108109
```
109110

110111
```swift
111-
let imageContentRequest = Request(
112+
let imageContentRequest = ReadingRequest(
112113
name: "image",
113114
arguments: [
114115
Argument(key: "role", value: "opener"),
@@ -139,7 +140,7 @@ let articleContent = Fragment(
139140
Finally, we put everything together as a `Query`. A Query always has a top level Request to get everything started, and requires all the Fragments that are used inside.
140141

141142
```swift
142-
let query = Query(withRequest: Request(
143+
let query = Query(readingRequest: ReadingRequest(
143144
withAlias: "test",
144145
name: "content",
145146
arguments: [
@@ -157,6 +158,62 @@ All we have to do now is to call `create()` on our Query and we're good to go.
157158
```
158159
print(query.create())
159160
```
161+
### Mutation
162+
Let's assume, we want to change our username and our age in our backend and we want to have the new name and age back to make sure everything went right.
163+
164+
Let's assume further, our server provides a mutating method `editMe` for exactly that purpose.
165+
166+
Our graphQL query for that will look like this:
167+
168+
```graphQL
169+
mutation myMutation {
170+
editMe(input: {
171+
name: "joe",
172+
age: 99
173+
})
174+
{
175+
name,
176+
age
177+
}
178+
}
179+
```
180+
Let us first create the actual mutating function. We can use a `MutatingRequest` for that. As `Argument` `values` we give information about which fields should be changed and what's the actual change
181+
182+
```swift
183+
let mutatingRequest = MutatingRequest(
184+
mutationName: "editMe",
185+
mutationArgument:
186+
Argument(
187+
key: "input",
188+
values: [
189+
Value(withFields: [
190+
MutatingField(key: "name", value: "joe"),
191+
MutatingField(key: "age", value: 99)
192+
]
193+
)
194+
]
195+
),
196+
responseFields: [
197+
"name",
198+
"age"
199+
]
200+
)
201+
```
202+
203+
We can then use a normal `Query` for that. The only difference is: We have to tell the query, that it will be a `Mutation`
204+
205+
```swift
206+
let mutation = Mutation(
207+
withAlias: "myMutation",
208+
mutatingRequest: mutatingRequest
209+
)
210+
```
211+
212+
After we've done that we can create the request.
213+
214+
```swift
215+
print(mutation.create())
216+
```
160217

161218
## Authors
162219
`GraphQLicious` was made in-house by WeltN24

Sample/ViewController.swift

Lines changed: 55 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,32 @@ class ViewController: UIViewController {
1414
override func viewDidLoad() {
1515
super.viewDidLoad()
1616

17-
18-
19-
/**
20-
Let's assume, we have the id of an article and we want to have the
17+
/**
18+
Let's assume, we have the id of an article and we want to have the
2119
headline, body text and opener image of that article.
2220

2321
First, let's create a fragment to fetch the contents
2422
of an image, namely the image `id` and the image `url`
2523
*/
26-
27-
let urlFragment = Fragment(
28-
withAlias: "urlFragment",
29-
name: "Image",
30-
fields: [
31-
Request(
32-
name: "url",
33-
arguments: [
34-
Argument(key: "ratio", value: 1),
35-
Argument(key: "size", value: 200)
36-
]
37-
)
38-
]
39-
)
40-
4124
let imageContent = Fragment(
4225
withAlias: "imageContent",
4326
name: "Image",
4427
fields: [
4528
"id",
46-
urlFragment
29+
"url"
4730
]
4831
)
4932

50-
/**
51-
Next, let's embed the fragment into a request that gets the opener image.
33+
/**Next, let's embed the `Fragment` into a `Request` that gets the opener image.
5234
Note: Argument values that are of type String, are automatically represented with quotes.
53-
54-
GraphQL also gives us the possibility to have custom enums as argument values. All
55-
we have to do, is letting our enum implement ArgumentValue and we're good to go.
35+
GraphQL also gives us the possibility to have custom enums as argument values.
36+
All you have to do, is letting your enum implement ArgumentValue and you're good to go.
5637
*/
5738
enum customEnum: String, ArgumentValue {
5839
case This = "this"
5940
case That = "that"
6041

61-
private var asGraphQLArgument: String {
42+
var asGraphQLArgument: String {
6243
return rawValue // without quotes
6344
}
6445
}
@@ -70,12 +51,11 @@ class ViewController: UIViewController {
7051
customEnum.That
7152
]
7253
)
73-
74-
let imageContentRequest = Request(
54+
55+
let imageContentRequest = ReadingRequest(
7556
name: "images",
7657
arguments: [
77-
Argument(key: "role", value: "opener"),
78-
customEnumArgument
58+
Argument(key: "role", value: "opener")
7959
],
8060
fields: [
8161
imageContent
@@ -87,7 +67,7 @@ class ViewController: UIViewController {
8767
If we want to, we can imbed that request into another fragment.
8868
(We can also embed fragments into fragments)
8969

90-
Additionally to the opener image with its id and url we also want the headline and
70+
Additionally to the opener image with its id and url we also want the headline and
9171
body text of the article.
9272
*/
9373
let articleContent = Fragment(
@@ -105,41 +85,63 @@ class ViewController: UIViewController {
10585
A query always has a top level request to get everything started,
10686
and requires all the fragments that are used inside.
10787
*/
108-
let q1 = Query(withRequest: Request(
88+
let q1 = Query(readingRequest: ReadingRequest(
10989
withAlias: "test",
11090
name: "content",
11191
arguments: [
112-
Argument(key: "ids", values: [153082687])
92+
Argument(key: "ids", values: [153082687]),
93+
customEnumArgument
11394
],
11495
fields: [
11596
articleContent
11697
]),
117-
fragments: [articleContent, imageContent, urlFragment]
98+
fragments: [articleContent, imageContent]
11899
)
119100

120101
/**
121-
{
122-
test: content(id: 153082687){
123-
...contentFields
124-
}
125-
}
126-
fragment contentFields on Content {
127-
headline,
128-
body,
129-
image(role: "opener", enum: [this, that]){
130-
...imageContent
131-
}
132-
}
133-
fragment imageContent on Image {
134-
id
135-
...urlFragment
136-
}
137-
fragment urlFragment on Image {
138-
url (ratio: 1, size: 200)
139-
}
102+
All we have to do now is to call `create()` on our Query and we're good to go.
140103
*/
141104
print(q1.create())
142105
debugPrint(q1)
106+
107+
/**
108+
Let's assume, we want to change our username and our age in our backend and we want to have the
109+
new name and age back to make sure everything went right.
110+
Let's assume further, our server provides a mutating method `editMe` for exactly that purpose.
111+
112+
Let us first create the actual mutating request. We can use a `MutatingRequest` for that.
113+
*/
114+
115+
let mutatingRequest = MutatingRequest(
116+
mutationName: "editMe",
117+
mutationArgument:
118+
Argument(
119+
key: "input",
120+
values: [
121+
Value(withFields: [
122+
MutatingField(key: "name", value: "joe"),
123+
MutatingField(key: "age", value: 99)
124+
]
125+
)
126+
]
127+
),
128+
responseFields: [
129+
"name",
130+
"age"
131+
]
132+
)
133+
134+
/**
135+
We can then use a normal `Query` for that. The only difference is: We have to tell the query,
136+
that it will be a `Mutation`
137+
*/
138+
let mutation = Mutation(
139+
withAlias: "myMutation",
140+
mutatingRequest: mutatingRequest
141+
)
142+
143+
print(mutation.create())
144+
debugPrint(mutation)
143145
}
144146

145147
override func didReceiveMemoryWarning() {

0 commit comments

Comments
 (0)