├── .gitignore
├── .swiftpm
└── xcode
│ ├── package.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── swapnilnandgave.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ ├── xcshareddata
│ └── xcschemes
│ │ └── ODataSwift.xcscheme
│ └── xcuserdata
│ └── swapnilnandgave.xcuserdatad
│ └── xcschemes
│ └── xcschememanagement.plist
├── Examples
└── Example-iOS
│ └── ODataSwiftExample
│ ├── ODataSwiftExample.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── ODataSwiftExample.xcscheme
│ └── xcuserdata
│ │ └── swapnilnandgave.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
│ ├── ODataSwiftExample
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── ViewController.swift
│ ├── ODataSwiftExampleTests
│ ├── Info.plist
│ └── ODataSwiftExampleTests.swift
│ └── ODataSwiftExampleUITests
│ ├── Info.plist
│ └── ODataSwiftExampleUITests.swift
├── LICENSE
├── ODataSwift.podspec
├── ODataSwift.xcworkspace
├── contents.xcworkspacedata
├── xcshareddata
│ ├── IDEWorkspaceChecks.plist
│ └── WorkspaceSettings.xcsettings
└── xcuserdata
│ └── swapnilnandgave.xcuserdatad
│ ├── UserInterfaceState.xcuserstate
│ ├── WorkspaceSettings.xcsettings
│ └── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
├── Package.swift
├── README.md
├── Sources
└── ODataSwift
│ ├── Count.swift
│ ├── DateTime.swift
│ ├── Error.swift
│ ├── Expand.swift
│ ├── Filter.swift
│ ├── Funtion.swift
│ ├── ODataQueryBuilder.swift
│ ├── Order.swift
│ ├── QueryConvertible.swift
│ ├── QueryOption.swift
│ └── Search.swift
└── Tests
├── LinuxMain.swift
└── ODataSwiftTests
├── ODataSwiftTests.swift
└── XCTestManifests.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## Other
29 | *.moved-aside
30 | *.xcuserstate
31 |
32 | ## App packaging
33 | *.ipa
34 | *.dSYM.zip
35 | *.dSYM
36 |
37 | ## Playgrounds
38 | timeline.xctimeline
39 | playground.xcworkspace
40 |
41 | # Swift Package Manager
42 | #
43 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
44 | # Packages/
45 | # Package.pins
46 | # Package.resolved
47 | # *.xcodeproj
48 | #
49 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
50 | # hence it is not needed unless you have added a package configuration file to your project
51 | # .swiftpm
52 |
53 | .build/
54 |
55 | # CocoaPods
56 | #
57 | # We recommend against adding the Pods directory to your .gitignore. However
58 | # you should judge for yourself, the pros and cons are mentioned at:
59 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
60 | #
61 | # Pods/
62 | #
63 | # Add this line if you want to avoid checking in source code from the Xcode workspace
64 | # *.xcworkspace
65 |
66 | # Carthage
67 | #
68 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
69 | # Carthage/Checkouts
70 |
71 | Carthage/Build/
72 |
73 | # Accio dependency management
74 | Dependencies/
75 | .accio/
76 |
77 | # fastlane
78 | #
79 | # It is recommended to not store the screenshots in the git repo.
80 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
81 | # For more information about the recommended setup visit:
82 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
83 |
84 | fastlane/report.xml
85 | fastlane/Preview.html
86 | fastlane/screenshots/**/*.png
87 | fastlane/test_output
88 |
89 | # Code Injection
90 | #
91 | # After new code Injection tools there's a generated folder /iOSInjectionProject
92 | # https://github.com/johnno1962/injectionforxcode
93 |
94 | iOSInjectionProject/
95 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/xcuserdata/swapnilnandgave.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/developer-celusion/ODataSwift/3d1fb9bfc0ac33a4e662fbb1dd7382489c2fa981/.swiftpm/xcode/package.xcworkspace/xcuserdata/swapnilnandgave.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/.swiftpm/xcode/xcshareddata/xcschemes/ODataSwift.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
67 |
68 |
74 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/xcuserdata/swapnilnandgave.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ODataSwift.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | ODataSwift
16 |
17 | primary
18 |
19 |
20 | ODataSwiftTests
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 52;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | B85BED4A23BDF6C4006CD507 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85BED4923BDF6C4006CD507 /* AppDelegate.swift */; };
11 | B85BED4C23BDF6C4006CD507 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85BED4B23BDF6C4006CD507 /* SceneDelegate.swift */; };
12 | B85BED4E23BDF6C4006CD507 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85BED4D23BDF6C4006CD507 /* ViewController.swift */; };
13 | B85BED5123BDF6C4006CD507 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B85BED4F23BDF6C4006CD507 /* Main.storyboard */; };
14 | B85BED5323BDF6C7006CD507 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B85BED5223BDF6C7006CD507 /* Assets.xcassets */; };
15 | B85BED5623BDF6C7006CD507 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B85BED5423BDF6C7006CD507 /* LaunchScreen.storyboard */; };
16 | B85BED6123BDF6C8006CD507 /* ODataSwiftExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85BED6023BDF6C8006CD507 /* ODataSwiftExampleTests.swift */; };
17 | B85BED6C23BDF6C8006CD507 /* ODataSwiftExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85BED6B23BDF6C8006CD507 /* ODataSwiftExampleUITests.swift */; };
18 | B85BED7B23BDF724006CD507 /* ODataSwift in Frameworks */ = {isa = PBXBuildFile; productRef = B85BED7A23BDF724006CD507 /* ODataSwift */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXContainerItemProxy section */
22 | B85BED5D23BDF6C8006CD507 /* PBXContainerItemProxy */ = {
23 | isa = PBXContainerItemProxy;
24 | containerPortal = B85BED3E23BDF6C4006CD507 /* Project object */;
25 | proxyType = 1;
26 | remoteGlobalIDString = B85BED4523BDF6C4006CD507;
27 | remoteInfo = ODataSwiftExample;
28 | };
29 | B85BED6823BDF6C8006CD507 /* PBXContainerItemProxy */ = {
30 | isa = PBXContainerItemProxy;
31 | containerPortal = B85BED3E23BDF6C4006CD507 /* Project object */;
32 | proxyType = 1;
33 | remoteGlobalIDString = B85BED4523BDF6C4006CD507;
34 | remoteInfo = ODataSwiftExample;
35 | };
36 | /* End PBXContainerItemProxy section */
37 |
38 | /* Begin PBXFileReference section */
39 | B85BED4623BDF6C4006CD507 /* ODataSwiftExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ODataSwiftExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
40 | B85BED4923BDF6C4006CD507 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
41 | B85BED4B23BDF6C4006CD507 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
42 | B85BED4D23BDF6C4006CD507 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
43 | B85BED5023BDF6C4006CD507 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
44 | B85BED5223BDF6C7006CD507 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
45 | B85BED5523BDF6C7006CD507 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
46 | B85BED5723BDF6C7006CD507 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
47 | B85BED5C23BDF6C8006CD507 /* ODataSwiftExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ODataSwiftExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
48 | B85BED6023BDF6C8006CD507 /* ODataSwiftExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ODataSwiftExampleTests.swift; sourceTree = ""; };
49 | B85BED6223BDF6C8006CD507 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
50 | B85BED6723BDF6C8006CD507 /* ODataSwiftExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ODataSwiftExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
51 | B85BED6B23BDF6C8006CD507 /* ODataSwiftExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ODataSwiftExampleUITests.swift; sourceTree = ""; };
52 | B85BED6D23BDF6C8006CD507 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
53 | /* End PBXFileReference section */
54 |
55 | /* Begin PBXFrameworksBuildPhase section */
56 | B85BED4323BDF6C4006CD507 /* Frameworks */ = {
57 | isa = PBXFrameworksBuildPhase;
58 | buildActionMask = 2147483647;
59 | files = (
60 | B85BED7B23BDF724006CD507 /* ODataSwift in Frameworks */,
61 | );
62 | runOnlyForDeploymentPostprocessing = 0;
63 | };
64 | B85BED5923BDF6C8006CD507 /* Frameworks */ = {
65 | isa = PBXFrameworksBuildPhase;
66 | buildActionMask = 2147483647;
67 | files = (
68 | );
69 | runOnlyForDeploymentPostprocessing = 0;
70 | };
71 | B85BED6423BDF6C8006CD507 /* Frameworks */ = {
72 | isa = PBXFrameworksBuildPhase;
73 | buildActionMask = 2147483647;
74 | files = (
75 | );
76 | runOnlyForDeploymentPostprocessing = 0;
77 | };
78 | /* End PBXFrameworksBuildPhase section */
79 |
80 | /* Begin PBXGroup section */
81 | B85BED3D23BDF6C4006CD507 = {
82 | isa = PBXGroup;
83 | children = (
84 | B85BED4823BDF6C4006CD507 /* ODataSwiftExample */,
85 | B85BED5F23BDF6C8006CD507 /* ODataSwiftExampleTests */,
86 | B85BED6A23BDF6C8006CD507 /* ODataSwiftExampleUITests */,
87 | B85BED4723BDF6C4006CD507 /* Products */,
88 | B85BED7923BDF724006CD507 /* Frameworks */,
89 | );
90 | sourceTree = "";
91 | };
92 | B85BED4723BDF6C4006CD507 /* Products */ = {
93 | isa = PBXGroup;
94 | children = (
95 | B85BED4623BDF6C4006CD507 /* ODataSwiftExample.app */,
96 | B85BED5C23BDF6C8006CD507 /* ODataSwiftExampleTests.xctest */,
97 | B85BED6723BDF6C8006CD507 /* ODataSwiftExampleUITests.xctest */,
98 | );
99 | name = Products;
100 | sourceTree = "";
101 | };
102 | B85BED4823BDF6C4006CD507 /* ODataSwiftExample */ = {
103 | isa = PBXGroup;
104 | children = (
105 | B85BED4923BDF6C4006CD507 /* AppDelegate.swift */,
106 | B85BED4B23BDF6C4006CD507 /* SceneDelegate.swift */,
107 | B85BED4D23BDF6C4006CD507 /* ViewController.swift */,
108 | B85BED4F23BDF6C4006CD507 /* Main.storyboard */,
109 | B85BED5223BDF6C7006CD507 /* Assets.xcassets */,
110 | B85BED5423BDF6C7006CD507 /* LaunchScreen.storyboard */,
111 | B85BED5723BDF6C7006CD507 /* Info.plist */,
112 | );
113 | path = ODataSwiftExample;
114 | sourceTree = "";
115 | };
116 | B85BED5F23BDF6C8006CD507 /* ODataSwiftExampleTests */ = {
117 | isa = PBXGroup;
118 | children = (
119 | B85BED6023BDF6C8006CD507 /* ODataSwiftExampleTests.swift */,
120 | B85BED6223BDF6C8006CD507 /* Info.plist */,
121 | );
122 | path = ODataSwiftExampleTests;
123 | sourceTree = "";
124 | };
125 | B85BED6A23BDF6C8006CD507 /* ODataSwiftExampleUITests */ = {
126 | isa = PBXGroup;
127 | children = (
128 | B85BED6B23BDF6C8006CD507 /* ODataSwiftExampleUITests.swift */,
129 | B85BED6D23BDF6C8006CD507 /* Info.plist */,
130 | );
131 | path = ODataSwiftExampleUITests;
132 | sourceTree = "";
133 | };
134 | B85BED7923BDF724006CD507 /* Frameworks */ = {
135 | isa = PBXGroup;
136 | children = (
137 | );
138 | name = Frameworks;
139 | sourceTree = "";
140 | };
141 | /* End PBXGroup section */
142 |
143 | /* Begin PBXNativeTarget section */
144 | B85BED4523BDF6C4006CD507 /* ODataSwiftExample */ = {
145 | isa = PBXNativeTarget;
146 | buildConfigurationList = B85BED7023BDF6C8006CD507 /* Build configuration list for PBXNativeTarget "ODataSwiftExample" */;
147 | buildPhases = (
148 | B85BED4223BDF6C4006CD507 /* Sources */,
149 | B85BED4323BDF6C4006CD507 /* Frameworks */,
150 | B85BED4423BDF6C4006CD507 /* Resources */,
151 | );
152 | buildRules = (
153 | );
154 | dependencies = (
155 | );
156 | name = ODataSwiftExample;
157 | packageProductDependencies = (
158 | B85BED7A23BDF724006CD507 /* ODataSwift */,
159 | );
160 | productName = ODataSwiftExample;
161 | productReference = B85BED4623BDF6C4006CD507 /* ODataSwiftExample.app */;
162 | productType = "com.apple.product-type.application";
163 | };
164 | B85BED5B23BDF6C8006CD507 /* ODataSwiftExampleTests */ = {
165 | isa = PBXNativeTarget;
166 | buildConfigurationList = B85BED7323BDF6C8006CD507 /* Build configuration list for PBXNativeTarget "ODataSwiftExampleTests" */;
167 | buildPhases = (
168 | B85BED5823BDF6C8006CD507 /* Sources */,
169 | B85BED5923BDF6C8006CD507 /* Frameworks */,
170 | B85BED5A23BDF6C8006CD507 /* Resources */,
171 | );
172 | buildRules = (
173 | );
174 | dependencies = (
175 | B85BED5E23BDF6C8006CD507 /* PBXTargetDependency */,
176 | );
177 | name = ODataSwiftExampleTests;
178 | productName = ODataSwiftExampleTests;
179 | productReference = B85BED5C23BDF6C8006CD507 /* ODataSwiftExampleTests.xctest */;
180 | productType = "com.apple.product-type.bundle.unit-test";
181 | };
182 | B85BED6623BDF6C8006CD507 /* ODataSwiftExampleUITests */ = {
183 | isa = PBXNativeTarget;
184 | buildConfigurationList = B85BED7623BDF6C8006CD507 /* Build configuration list for PBXNativeTarget "ODataSwiftExampleUITests" */;
185 | buildPhases = (
186 | B85BED6323BDF6C8006CD507 /* Sources */,
187 | B85BED6423BDF6C8006CD507 /* Frameworks */,
188 | B85BED6523BDF6C8006CD507 /* Resources */,
189 | );
190 | buildRules = (
191 | );
192 | dependencies = (
193 | B85BED6923BDF6C8006CD507 /* PBXTargetDependency */,
194 | );
195 | name = ODataSwiftExampleUITests;
196 | productName = ODataSwiftExampleUITests;
197 | productReference = B85BED6723BDF6C8006CD507 /* ODataSwiftExampleUITests.xctest */;
198 | productType = "com.apple.product-type.bundle.ui-testing";
199 | };
200 | /* End PBXNativeTarget section */
201 |
202 | /* Begin PBXProject section */
203 | B85BED3E23BDF6C4006CD507 /* Project object */ = {
204 | isa = PBXProject;
205 | attributes = {
206 | LastSwiftUpdateCheck = 1120;
207 | LastUpgradeCheck = 1120;
208 | ORGANIZATIONNAME = "Celusion Technologies";
209 | TargetAttributes = {
210 | B85BED4523BDF6C4006CD507 = {
211 | CreatedOnToolsVersion = 11.2.1;
212 | };
213 | B85BED5B23BDF6C8006CD507 = {
214 | CreatedOnToolsVersion = 11.2.1;
215 | TestTargetID = B85BED4523BDF6C4006CD507;
216 | };
217 | B85BED6623BDF6C8006CD507 = {
218 | CreatedOnToolsVersion = 11.2.1;
219 | TestTargetID = B85BED4523BDF6C4006CD507;
220 | };
221 | };
222 | };
223 | buildConfigurationList = B85BED4123BDF6C4006CD507 /* Build configuration list for PBXProject "ODataSwiftExample" */;
224 | compatibilityVersion = "Xcode 9.3";
225 | developmentRegion = en;
226 | hasScannedForEncodings = 0;
227 | knownRegions = (
228 | en,
229 | Base,
230 | );
231 | mainGroup = B85BED3D23BDF6C4006CD507;
232 | productRefGroup = B85BED4723BDF6C4006CD507 /* Products */;
233 | projectDirPath = "";
234 | projectRoot = "";
235 | targets = (
236 | B85BED4523BDF6C4006CD507 /* ODataSwiftExample */,
237 | B85BED5B23BDF6C8006CD507 /* ODataSwiftExampleTests */,
238 | B85BED6623BDF6C8006CD507 /* ODataSwiftExampleUITests */,
239 | );
240 | };
241 | /* End PBXProject section */
242 |
243 | /* Begin PBXResourcesBuildPhase section */
244 | B85BED4423BDF6C4006CD507 /* Resources */ = {
245 | isa = PBXResourcesBuildPhase;
246 | buildActionMask = 2147483647;
247 | files = (
248 | B85BED5623BDF6C7006CD507 /* LaunchScreen.storyboard in Resources */,
249 | B85BED5323BDF6C7006CD507 /* Assets.xcassets in Resources */,
250 | B85BED5123BDF6C4006CD507 /* Main.storyboard in Resources */,
251 | );
252 | runOnlyForDeploymentPostprocessing = 0;
253 | };
254 | B85BED5A23BDF6C8006CD507 /* Resources */ = {
255 | isa = PBXResourcesBuildPhase;
256 | buildActionMask = 2147483647;
257 | files = (
258 | );
259 | runOnlyForDeploymentPostprocessing = 0;
260 | };
261 | B85BED6523BDF6C8006CD507 /* Resources */ = {
262 | isa = PBXResourcesBuildPhase;
263 | buildActionMask = 2147483647;
264 | files = (
265 | );
266 | runOnlyForDeploymentPostprocessing = 0;
267 | };
268 | /* End PBXResourcesBuildPhase section */
269 |
270 | /* Begin PBXSourcesBuildPhase section */
271 | B85BED4223BDF6C4006CD507 /* Sources */ = {
272 | isa = PBXSourcesBuildPhase;
273 | buildActionMask = 2147483647;
274 | files = (
275 | B85BED4E23BDF6C4006CD507 /* ViewController.swift in Sources */,
276 | B85BED4A23BDF6C4006CD507 /* AppDelegate.swift in Sources */,
277 | B85BED4C23BDF6C4006CD507 /* SceneDelegate.swift in Sources */,
278 | );
279 | runOnlyForDeploymentPostprocessing = 0;
280 | };
281 | B85BED5823BDF6C8006CD507 /* Sources */ = {
282 | isa = PBXSourcesBuildPhase;
283 | buildActionMask = 2147483647;
284 | files = (
285 | B85BED6123BDF6C8006CD507 /* ODataSwiftExampleTests.swift in Sources */,
286 | );
287 | runOnlyForDeploymentPostprocessing = 0;
288 | };
289 | B85BED6323BDF6C8006CD507 /* Sources */ = {
290 | isa = PBXSourcesBuildPhase;
291 | buildActionMask = 2147483647;
292 | files = (
293 | B85BED6C23BDF6C8006CD507 /* ODataSwiftExampleUITests.swift in Sources */,
294 | );
295 | runOnlyForDeploymentPostprocessing = 0;
296 | };
297 | /* End PBXSourcesBuildPhase section */
298 |
299 | /* Begin PBXTargetDependency section */
300 | B85BED5E23BDF6C8006CD507 /* PBXTargetDependency */ = {
301 | isa = PBXTargetDependency;
302 | target = B85BED4523BDF6C4006CD507 /* ODataSwiftExample */;
303 | targetProxy = B85BED5D23BDF6C8006CD507 /* PBXContainerItemProxy */;
304 | };
305 | B85BED6923BDF6C8006CD507 /* PBXTargetDependency */ = {
306 | isa = PBXTargetDependency;
307 | target = B85BED4523BDF6C4006CD507 /* ODataSwiftExample */;
308 | targetProxy = B85BED6823BDF6C8006CD507 /* PBXContainerItemProxy */;
309 | };
310 | /* End PBXTargetDependency section */
311 |
312 | /* Begin PBXVariantGroup section */
313 | B85BED4F23BDF6C4006CD507 /* Main.storyboard */ = {
314 | isa = PBXVariantGroup;
315 | children = (
316 | B85BED5023BDF6C4006CD507 /* Base */,
317 | );
318 | name = Main.storyboard;
319 | sourceTree = "";
320 | };
321 | B85BED5423BDF6C7006CD507 /* LaunchScreen.storyboard */ = {
322 | isa = PBXVariantGroup;
323 | children = (
324 | B85BED5523BDF6C7006CD507 /* Base */,
325 | );
326 | name = LaunchScreen.storyboard;
327 | sourceTree = "";
328 | };
329 | /* End PBXVariantGroup section */
330 |
331 | /* Begin XCBuildConfiguration section */
332 | B85BED6E23BDF6C8006CD507 /* Debug */ = {
333 | isa = XCBuildConfiguration;
334 | buildSettings = {
335 | ALWAYS_SEARCH_USER_PATHS = NO;
336 | CLANG_ANALYZER_NONNULL = YES;
337 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
338 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
339 | CLANG_CXX_LIBRARY = "libc++";
340 | CLANG_ENABLE_MODULES = YES;
341 | CLANG_ENABLE_OBJC_ARC = YES;
342 | CLANG_ENABLE_OBJC_WEAK = YES;
343 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
344 | CLANG_WARN_BOOL_CONVERSION = YES;
345 | CLANG_WARN_COMMA = YES;
346 | CLANG_WARN_CONSTANT_CONVERSION = YES;
347 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
348 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
349 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
350 | CLANG_WARN_EMPTY_BODY = YES;
351 | CLANG_WARN_ENUM_CONVERSION = YES;
352 | CLANG_WARN_INFINITE_RECURSION = YES;
353 | CLANG_WARN_INT_CONVERSION = YES;
354 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
355 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
356 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
357 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
358 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
359 | CLANG_WARN_STRICT_PROTOTYPES = YES;
360 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
361 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
362 | CLANG_WARN_UNREACHABLE_CODE = YES;
363 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
364 | COPY_PHASE_STRIP = NO;
365 | DEBUG_INFORMATION_FORMAT = dwarf;
366 | ENABLE_STRICT_OBJC_MSGSEND = YES;
367 | ENABLE_TESTABILITY = YES;
368 | GCC_C_LANGUAGE_STANDARD = gnu11;
369 | GCC_DYNAMIC_NO_PIC = NO;
370 | GCC_NO_COMMON_BLOCKS = YES;
371 | GCC_OPTIMIZATION_LEVEL = 0;
372 | GCC_PREPROCESSOR_DEFINITIONS = (
373 | "DEBUG=1",
374 | "$(inherited)",
375 | );
376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
378 | GCC_WARN_UNDECLARED_SELECTOR = YES;
379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
380 | GCC_WARN_UNUSED_FUNCTION = YES;
381 | GCC_WARN_UNUSED_VARIABLE = YES;
382 | IPHONEOS_DEPLOYMENT_TARGET = 13.2;
383 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
384 | MTL_FAST_MATH = YES;
385 | ONLY_ACTIVE_ARCH = YES;
386 | SDKROOT = iphoneos;
387 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
388 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
389 | };
390 | name = Debug;
391 | };
392 | B85BED6F23BDF6C8006CD507 /* Release */ = {
393 | isa = XCBuildConfiguration;
394 | buildSettings = {
395 | ALWAYS_SEARCH_USER_PATHS = NO;
396 | CLANG_ANALYZER_NONNULL = YES;
397 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
398 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
399 | CLANG_CXX_LIBRARY = "libc++";
400 | CLANG_ENABLE_MODULES = YES;
401 | CLANG_ENABLE_OBJC_ARC = YES;
402 | CLANG_ENABLE_OBJC_WEAK = YES;
403 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
404 | CLANG_WARN_BOOL_CONVERSION = YES;
405 | CLANG_WARN_COMMA = YES;
406 | CLANG_WARN_CONSTANT_CONVERSION = YES;
407 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
408 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
409 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
410 | CLANG_WARN_EMPTY_BODY = YES;
411 | CLANG_WARN_ENUM_CONVERSION = YES;
412 | CLANG_WARN_INFINITE_RECURSION = YES;
413 | CLANG_WARN_INT_CONVERSION = YES;
414 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
415 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
416 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
417 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
418 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
419 | CLANG_WARN_STRICT_PROTOTYPES = YES;
420 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
421 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
422 | CLANG_WARN_UNREACHABLE_CODE = YES;
423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
424 | COPY_PHASE_STRIP = NO;
425 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
426 | ENABLE_NS_ASSERTIONS = NO;
427 | ENABLE_STRICT_OBJC_MSGSEND = YES;
428 | GCC_C_LANGUAGE_STANDARD = gnu11;
429 | GCC_NO_COMMON_BLOCKS = YES;
430 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
431 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
432 | GCC_WARN_UNDECLARED_SELECTOR = YES;
433 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
434 | GCC_WARN_UNUSED_FUNCTION = YES;
435 | GCC_WARN_UNUSED_VARIABLE = YES;
436 | IPHONEOS_DEPLOYMENT_TARGET = 13.2;
437 | MTL_ENABLE_DEBUG_INFO = NO;
438 | MTL_FAST_MATH = YES;
439 | SDKROOT = iphoneos;
440 | SWIFT_COMPILATION_MODE = wholemodule;
441 | SWIFT_OPTIMIZATION_LEVEL = "-O";
442 | VALIDATE_PRODUCT = YES;
443 | };
444 | name = Release;
445 | };
446 | B85BED7123BDF6C8006CD507 /* Debug */ = {
447 | isa = XCBuildConfiguration;
448 | buildSettings = {
449 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
450 | CODE_SIGN_STYLE = Automatic;
451 | INFOPLIST_FILE = ODataSwiftExample/Info.plist;
452 | LD_RUNPATH_SEARCH_PATHS = (
453 | "$(inherited)",
454 | "@executable_path/Frameworks",
455 | );
456 | MARKETING_VERSION = 1.0.0;
457 | PRODUCT_BUNDLE_IDENTIFIER = com.celusion.ODataSwiftExample;
458 | PRODUCT_NAME = "$(TARGET_NAME)";
459 | SWIFT_VERSION = 5.0;
460 | TARGETED_DEVICE_FAMILY = "1,2";
461 | };
462 | name = Debug;
463 | };
464 | B85BED7223BDF6C8006CD507 /* Release */ = {
465 | isa = XCBuildConfiguration;
466 | buildSettings = {
467 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
468 | CODE_SIGN_STYLE = Automatic;
469 | INFOPLIST_FILE = ODataSwiftExample/Info.plist;
470 | LD_RUNPATH_SEARCH_PATHS = (
471 | "$(inherited)",
472 | "@executable_path/Frameworks",
473 | );
474 | MARKETING_VERSION = 1.0.0;
475 | PRODUCT_BUNDLE_IDENTIFIER = com.celusion.ODataSwiftExample;
476 | PRODUCT_NAME = "$(TARGET_NAME)";
477 | SWIFT_VERSION = 5.0;
478 | TARGETED_DEVICE_FAMILY = "1,2";
479 | };
480 | name = Release;
481 | };
482 | B85BED7423BDF6C8006CD507 /* Debug */ = {
483 | isa = XCBuildConfiguration;
484 | buildSettings = {
485 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
486 | BUNDLE_LOADER = "$(TEST_HOST)";
487 | CODE_SIGN_STYLE = Automatic;
488 | INFOPLIST_FILE = ODataSwiftExampleTests/Info.plist;
489 | IPHONEOS_DEPLOYMENT_TARGET = 13.2;
490 | LD_RUNPATH_SEARCH_PATHS = (
491 | "$(inherited)",
492 | "@executable_path/Frameworks",
493 | "@loader_path/Frameworks",
494 | );
495 | PRODUCT_BUNDLE_IDENTIFIER = com.celusion.ODataSwiftExampleTests;
496 | PRODUCT_NAME = "$(TARGET_NAME)";
497 | SWIFT_VERSION = 5.0;
498 | TARGETED_DEVICE_FAMILY = "1,2";
499 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ODataSwiftExample.app/ODataSwiftExample";
500 | };
501 | name = Debug;
502 | };
503 | B85BED7523BDF6C8006CD507 /* Release */ = {
504 | isa = XCBuildConfiguration;
505 | buildSettings = {
506 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
507 | BUNDLE_LOADER = "$(TEST_HOST)";
508 | CODE_SIGN_STYLE = Automatic;
509 | INFOPLIST_FILE = ODataSwiftExampleTests/Info.plist;
510 | IPHONEOS_DEPLOYMENT_TARGET = 13.2;
511 | LD_RUNPATH_SEARCH_PATHS = (
512 | "$(inherited)",
513 | "@executable_path/Frameworks",
514 | "@loader_path/Frameworks",
515 | );
516 | PRODUCT_BUNDLE_IDENTIFIER = com.celusion.ODataSwiftExampleTests;
517 | PRODUCT_NAME = "$(TARGET_NAME)";
518 | SWIFT_VERSION = 5.0;
519 | TARGETED_DEVICE_FAMILY = "1,2";
520 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ODataSwiftExample.app/ODataSwiftExample";
521 | };
522 | name = Release;
523 | };
524 | B85BED7723BDF6C8006CD507 /* Debug */ = {
525 | isa = XCBuildConfiguration;
526 | buildSettings = {
527 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
528 | CODE_SIGN_STYLE = Automatic;
529 | INFOPLIST_FILE = ODataSwiftExampleUITests/Info.plist;
530 | LD_RUNPATH_SEARCH_PATHS = (
531 | "$(inherited)",
532 | "@executable_path/Frameworks",
533 | "@loader_path/Frameworks",
534 | );
535 | PRODUCT_BUNDLE_IDENTIFIER = com.celusion.ODataSwiftExampleUITests;
536 | PRODUCT_NAME = "$(TARGET_NAME)";
537 | SWIFT_VERSION = 5.0;
538 | TARGETED_DEVICE_FAMILY = "1,2";
539 | TEST_TARGET_NAME = ODataSwiftExample;
540 | };
541 | name = Debug;
542 | };
543 | B85BED7823BDF6C8006CD507 /* Release */ = {
544 | isa = XCBuildConfiguration;
545 | buildSettings = {
546 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
547 | CODE_SIGN_STYLE = Automatic;
548 | INFOPLIST_FILE = ODataSwiftExampleUITests/Info.plist;
549 | LD_RUNPATH_SEARCH_PATHS = (
550 | "$(inherited)",
551 | "@executable_path/Frameworks",
552 | "@loader_path/Frameworks",
553 | );
554 | PRODUCT_BUNDLE_IDENTIFIER = com.celusion.ODataSwiftExampleUITests;
555 | PRODUCT_NAME = "$(TARGET_NAME)";
556 | SWIFT_VERSION = 5.0;
557 | TARGETED_DEVICE_FAMILY = "1,2";
558 | TEST_TARGET_NAME = ODataSwiftExample;
559 | };
560 | name = Release;
561 | };
562 | /* End XCBuildConfiguration section */
563 |
564 | /* Begin XCConfigurationList section */
565 | B85BED4123BDF6C4006CD507 /* Build configuration list for PBXProject "ODataSwiftExample" */ = {
566 | isa = XCConfigurationList;
567 | buildConfigurations = (
568 | B85BED6E23BDF6C8006CD507 /* Debug */,
569 | B85BED6F23BDF6C8006CD507 /* Release */,
570 | );
571 | defaultConfigurationIsVisible = 0;
572 | defaultConfigurationName = Release;
573 | };
574 | B85BED7023BDF6C8006CD507 /* Build configuration list for PBXNativeTarget "ODataSwiftExample" */ = {
575 | isa = XCConfigurationList;
576 | buildConfigurations = (
577 | B85BED7123BDF6C8006CD507 /* Debug */,
578 | B85BED7223BDF6C8006CD507 /* Release */,
579 | );
580 | defaultConfigurationIsVisible = 0;
581 | defaultConfigurationName = Release;
582 | };
583 | B85BED7323BDF6C8006CD507 /* Build configuration list for PBXNativeTarget "ODataSwiftExampleTests" */ = {
584 | isa = XCConfigurationList;
585 | buildConfigurations = (
586 | B85BED7423BDF6C8006CD507 /* Debug */,
587 | B85BED7523BDF6C8006CD507 /* Release */,
588 | );
589 | defaultConfigurationIsVisible = 0;
590 | defaultConfigurationName = Release;
591 | };
592 | B85BED7623BDF6C8006CD507 /* Build configuration list for PBXNativeTarget "ODataSwiftExampleUITests" */ = {
593 | isa = XCConfigurationList;
594 | buildConfigurations = (
595 | B85BED7723BDF6C8006CD507 /* Debug */,
596 | B85BED7823BDF6C8006CD507 /* Release */,
597 | );
598 | defaultConfigurationIsVisible = 0;
599 | defaultConfigurationName = Release;
600 | };
601 | /* End XCConfigurationList section */
602 |
603 | /* Begin XCSwiftPackageProductDependency section */
604 | B85BED7A23BDF724006CD507 /* ODataSwift */ = {
605 | isa = XCSwiftPackageProductDependency;
606 | productName = ODataSwift;
607 | };
608 | /* End XCSwiftPackageProductDependency section */
609 | };
610 | rootObject = B85BED3E23BDF6C4006CD507 /* Project object */;
611 | }
612 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample.xcodeproj/xcshareddata/xcschemes/ODataSwiftExample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
63 |
65 |
71 |
72 |
73 |
74 |
80 |
82 |
88 |
89 |
90 |
91 |
93 |
94 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample.xcodeproj/xcuserdata/swapnilnandgave.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ODataSwiftExample.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 1
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | B85BED4523BDF6C4006CD507
16 |
17 | primary
18 |
19 |
20 | B85BED5B23BDF6C8006CD507
21 |
22 | primary
23 |
24 |
25 | B85BED6623BDF6C8006CD507
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ODataSwiftExample
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | // Copyright © 2020 Celusion Technologies. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
29 |
37 |
45 |
54 |
62 |
70 |
78 |
86 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | $(MARKETING_VERSION)
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 | UISupportedInterfaceOrientations~ipad
57 |
58 | UIInterfaceOrientationPortrait
59 | UIInterfaceOrientationPortraitUpsideDown
60 | UIInterfaceOrientationLandscapeLeft
61 | UIInterfaceOrientationLandscapeRight
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // ODataSwiftExample
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | // Copyright © 2020 Celusion Technologies. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
20 | guard let _ = (scene as? UIWindowScene) else { return }
21 | }
22 |
23 | func sceneDidDisconnect(_ scene: UIScene) {
24 | // Called as the scene is being released by the system.
25 | // This occurs shortly after the scene enters the background, or when its session is discarded.
26 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
28 | }
29 |
30 | func sceneDidBecomeActive(_ scene: UIScene) {
31 | // Called when the scene has moved from an inactive state to an active state.
32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
33 | }
34 |
35 | func sceneWillResignActive(_ scene: UIScene) {
36 | // Called when the scene will move from an active state to an inactive state.
37 | // This may occur due to temporary interruptions (ex. an incoming phone call).
38 | }
39 |
40 | func sceneWillEnterForeground(_ scene: UIScene) {
41 | // Called as the scene transitions from the background to the foreground.
42 | // Use this method to undo the changes made on entering the background.
43 | }
44 |
45 | func sceneDidEnterBackground(_ scene: UIScene) {
46 | // Called as the scene transitions from the foreground to the background.
47 | // Use this method to save data, release shared resources, and store enough scene-specific state information
48 | // to restore the scene back to its current state.
49 | }
50 |
51 |
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExample/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // ODataSwiftExample
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | // Copyright © 2020 Celusion Technologies. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ODataSwift
11 |
12 | class ViewController: UIViewController {
13 |
14 | @IBOutlet weak var labelGenQuery: UILabel!
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 | // Do any additional setup after loading the view.
19 | labelGenQuery.text = ""
20 | ODataQueryBuilder.configure(url: "https://services.odata.org/V4")
21 | }
22 |
23 | @IBAction func selectDidPressed(_ sender: Any) {
24 | let str = ODataQueryBuilder().entity("Airports").selects(["Name","IcaoCode"]).build()
25 | labelGenQuery.text = str
26 | }
27 |
28 | @IBAction func filterDidPressed(_ sender: Any) {
29 | let filter = FilterExp("FirstName").eq().value("Scott").and([FilterExp("FirstName").eq().value("Scott")])
30 | var str = ODataQueryBuilder().entity("People").filter(filter).build()
31 | str += "\n" + ODataQueryBuilder().entity("People").filter(FilterExp("username").contains().value("7")).build()
32 | labelGenQuery.text = str
33 | }
34 |
35 | @IBAction func expandDidPressed(_ sender: Any) {
36 | let filter = FilterExp("FirstName").eq().value("Scott").and([FilterExp("FirstName").eq().value("Scott")])
37 | let expand = Expand("Trips").filter(filter)
38 | let str = ODataQueryBuilder().entity("People").expand(expand).build()
39 | labelGenQuery.text = str
40 | }
41 |
42 | @IBAction func orderDidPressed(_ sender: Any) {
43 | let order = Order("EndsAt", orderType: .desc)
44 | let str = ODataQueryBuilder().entity("People").id("scottketchum", "Trips").order(order).build()
45 | labelGenQuery.text = str
46 | }
47 |
48 | @IBAction func topDidPressed(_ sender: Any) {
49 | let str = ODataQueryBuilder().entity("People").top(2).build()
50 | labelGenQuery.text = str
51 | }
52 |
53 | @IBAction func skipDidPressed(_ sender: Any) {
54 | let str = ODataQueryBuilder().entity("People").skip(18).build()
55 | labelGenQuery.text = str
56 | }
57 |
58 | @IBAction func countDidPressed(_ sender: Any) {
59 | var str = "Count Only: " + ODataQueryBuilder().entity("People").onlyCount().build()
60 | str += "\nWith Count: " + ODataQueryBuilder().entity("People").withCount().build()
61 | str += "\nInline Count: " + ODataQueryBuilder().entity("People").inlineCount("Name").build()
62 | labelGenQuery.text = str
63 | }
64 |
65 | @IBAction func searchDidPressed(_ sender: Any) {
66 | let str = ODataQueryBuilder().entity("People").search(Search("Name")).build()
67 | labelGenQuery.text = str
68 | }
69 |
70 | @IBAction func funcDidPressed(_ sender: Any) {
71 | var str = ODataQueryBuilder().entity("People").filter(FilterExp(PropertyFunc("name", Function.length)).eq().value(30)).build()
72 | str += "\n" + ODataQueryBuilder().entity("People").filter(FilterExp(PropertyFunc("designation", .tolower)).eq().value("director")).build()
73 | str += "\n" + ODataQueryBuilder().entity("People").filter(FilterExp(PropertyFunc("designation", .substring).value(1)).eq().value("di")).build()
74 | str += "\n" + ODataQueryBuilder().entity("People").filter(FilterExp(PropertyFunc("CreatedOn", .year)).eq().value(2018)).build()
75 | str += "\n" + ODataQueryBuilder().entity("People").filter(FilterExp("CreatedOn").lt().date(DateTime.now)).build()
76 | labelGenQuery.text = str
77 | }
78 |
79 | }
80 |
81 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExampleTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExampleTests/ODataSwiftExampleTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ODataSwiftExampleTests.swift
3 | // ODataSwiftExampleTests
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | // Copyright © 2020 Celusion Technologies. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import ODataSwiftExample
11 |
12 | class ODataSwiftExampleTests: XCTestCase {
13 |
14 | override func setUp() {
15 | // Put setup code here. This method is called before the invocation of each test method in the class.
16 | }
17 |
18 | override func tearDown() {
19 | // Put teardown code here. This method is called after the invocation of each test method in the class.
20 | }
21 |
22 | func testExample() {
23 | // This is an example of a functional test case.
24 | // Use XCTAssert and related functions to verify your tests produce the correct results.
25 | }
26 |
27 | func testPerformanceExample() {
28 | // This is an example of a performance test case.
29 | self.measure {
30 | // Put the code you want to measure the time of here.
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExampleUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/ODataSwiftExample/ODataSwiftExampleUITests/ODataSwiftExampleUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ODataSwiftExampleUITests.swift
3 | // ODataSwiftExampleUITests
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | // Copyright © 2020 Celusion Technologies. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class ODataSwiftExampleUITests: XCTestCase {
12 |
13 | override func setUp() {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 |
16 | // In UI tests it is usually best to stop immediately when a failure occurs.
17 | continueAfterFailure = false
18 |
19 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
20 | }
21 |
22 | override func tearDown() {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | }
25 |
26 | func testExample() {
27 | // UI tests must launch the application that they test.
28 | let app = XCUIApplication()
29 | app.launch()
30 |
31 | // Use recording to get started writing UI tests.
32 | // Use XCTAssert and related functions to verify your tests produce the correct results.
33 | }
34 |
35 | func testLaunchPerformance() {
36 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) {
37 | // This measures how long it takes to launch your application.
38 | measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) {
39 | XCUIApplication().launch()
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Celusion
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ODataSwift.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod lib lint ODataSwift.podspec' to ensure this is a
3 | # valid spec before submitting.
4 | #
5 | # Any lines starting with a # are optional, but their use is encouraged
6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
7 | #
8 |
9 | Pod::Spec.new do |s|
10 | s.name = 'ODataSwift'
11 | s.version = '1.0.1'
12 | s.summary = 'The utility package for OData Client in Swift'
13 |
14 | # This description is used to generate tags and improve search results.
15 | # * Think: What does it do? Why did you write it? What is the focus?
16 | # * Try to keep it short, snappy and to the point.
17 | # * Write the description between the DESC delimiters below.
18 | # * Finally, don't worry about the indent, CocoaPods strips it!
19 |
20 | s.description = <<-DESC
21 | ODataSwift is simple utility swift wrapper to generate OData Query V4 that works on iOS and OS X. Makes using ODataSwift builder pattern APIs extremely easy and much more palatable to use in Swift
22 | DESC
23 |
24 | s.homepage = 'https://github.com/developer-celusion/ODataSwift'
25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
26 | s.license = { :type => 'MIT', :file => 'LICENSE' }
27 | s.author = { 'developer@celusion.com' => 'developer@celusion.com' }
28 | s.source = { :git => 'https://github.com/developer-celusion/ODataSwift.git', :tag => s.version.to_s }
29 | # s.social_media_url = 'https://twitter.com/'
30 |
31 | s.ios.deployment_target = '9.0'
32 |
33 | s.source_files = 'Sources/ODataSwift/**/*'
34 |
35 | # s.resource_bundles = {
36 | # 'ODataSwift' => ['ODataSwift/Assets/*.png']
37 | # }
38 |
39 | # s.public_header_files = 'Pod/Classes/**/*.h'
40 | # s.frameworks = 'UIKit', 'MapKit'
41 | # s.dependency 'AFNetworking', '~> 2.3'
42 | # s.dependency 'Alamofire'
43 | end
44 |
--------------------------------------------------------------------------------
/ODataSwift.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ODataSwift.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ODataSwift.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ODataSwift.xcworkspace/xcuserdata/swapnilnandgave.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/developer-celusion/ODataSwift/3d1fb9bfc0ac33a4e662fbb1dd7382489c2fa981/ODataSwift.xcworkspace/xcuserdata/swapnilnandgave.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ODataSwift.xcworkspace/xcuserdata/swapnilnandgave.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildLocationStyle
6 | UseAppPreferences
7 | CustomBuildLocationType
8 | RelativeToDerivedData
9 | DerivedDataLocationStyle
10 | Default
11 | IssueFilterStyle
12 | ShowActiveSchemeOnly
13 | LiveSourceIssuesEnabled
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ODataSwift.xcworkspace/xcuserdata/swapnilnandgave.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
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: "ODataSwift",
8 | platforms: [.macOS(.v10_12),
9 | .iOS(.v10),
10 | .tvOS(.v10),
11 | .watchOS(.v3)],
12 | products: [
13 | // Products define the executables and libraries produced by a package, and make them visible to other packages.
14 | .library(
15 | name: "ODataSwift",
16 | targets: ["ODataSwift"]),
17 | ],
18 | dependencies: [
19 | // Dependencies declare other packages that this package depends on.
20 | // .package(url: /* package url */, from: "1.0.0"),
21 | ],
22 | targets: [
23 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
24 | // Targets can depend on other targets in this package, and on products in packages which this package depends on.
25 | .target(
26 | name: "ODataSwift",
27 | dependencies: []),
28 | .testTarget(
29 | name: "ODataSwiftTests",
30 | dependencies: ["ODataSwift"]),
31 | ],
32 | swiftLanguageVersions: [.v5]
33 | )
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ODataSwift
2 |
3 | ODataSwift is simple utility swift wrapper to generate OData Query V4 that works on iOS and OS X. Makes using ODataSwift builder pattern APIs extremely easy
4 | and much more palatable to use in Swift
5 |
6 | ## :bulb: Features
7 |
8 | - Used builder pattern to generate query
9 | - Support $select, $expand, $filter
10 | - Support odata pagination like $top, $skip
11 | - Support unbound and bound functions
12 | - Support almost all predicates like eq, lt, gt
13 | - Support date time funtions like now()
14 |
15 | ## :book: Usage
16 |
17 | ### :key: Basics
18 |
19 | #### Setting OData URL
20 | ```swift
21 | ODataQueryBuilder.configure(url: "https://services.odata.org/V4")
22 | ```
23 |
24 | ### :key: Querying Data
25 |
26 | #### $filter
27 | The `$filter` system query option allows clients to filter a collection of resources that are addressed by a request URL
28 | ```swift
29 | let filter = FilterExp("FirstName").eq().value("Scott").and([FilterExp("FirstName").eq().value("Scott")])
30 | print(ODataQueryBuilder().entity("People").filter(filter).build())
31 | ```
32 | #### $orderby
33 | The `$orderby` system query option allows clients to request resources in either ascending order using asc or descending order using desc
34 | ```swift
35 | let order = Order("EndsAt", orderType: .desc)
36 | print(ODataQueryBuilder().entity("People").order(order).build())
37 | ```
38 | #### $top
39 | The `$top` system query option requests the number of items in the queried collection to be included in the result
40 | ```swift
41 | print(ODataQueryBuilder().entity("People").top(2).build())
42 | ```
43 | #### $skip
44 | The `$skip` query option requests the number of items in the queried collection that are to be skipped and not included in the result
45 | ```swift
46 | print(ODataQueryBuilder().entity("People").skip(18).build())
47 | ```
48 | #### $count
49 | The `$count` system query option allows clients to request a count of the matching resources included with the resources in the response
50 | It is available in three as per odata request `.onlyCount()` `.withCount()` `inlineCount(property)`
51 | ```swift
52 | print(ODataQueryBuilder().entity("People").withCount().build())
53 | ```
54 | #### $expand
55 | The `$expand` system query option specifies the related resources to be included in line with retrieved resources along with `$select`, `$filter` like system query options
56 | ```swift
57 | let filter = FilterExp("FirstName").eq().value("Scott").and([FilterExp("FirstName").eq().value("Scott")])
58 | let expand = Expand("Trips").filter(filter)
59 | print(ODataQueryBuilder().entity("People").expand(expand).build())
60 | ```
61 | #### $select
62 | The `$select` system query option allows the clients to requests a limited set of properties for each entity
63 | ```swift
64 | print(ODataQueryBuilder().entity("Airports").selects(["Name","IcaoCode"]).build())
65 | ```
66 | #### $search
67 | The `$search` system query option restricts the result to include only those entities matching the specified search expression
68 | ```swift
69 | print(ODataQueryBuilder().entity("People").search(Search("Name")).build())
70 | ```
71 | #### Advanced Query Generation by OData Functions
72 | ```swift
73 | let url = ODataQueryBuilder().entity("People").filter(FilterExp(PropertyFunc("name", .length)).eq().value(30)).build()
74 | print(url)
75 | ```
76 | ```swift
77 | let url = ODataQueryBuilder().entity("People").filter(FilterExp(PropertyFunc("designation", .substring).value(1)).eq().value("di")).build()
78 | print(url)
79 | ```
80 | ```swift
81 | let url = ODataQueryBuilder().entity("People").filter(FilterExp(PropertyFunc("CreatedOn", .year)).eq().value(2020)).build()
82 | print(url)
83 | ```
84 |
85 | #### URL Encode
86 | Use default `.encode()` method to get string presentation of OData URL for network calls
87 | ```swift
88 | let urlEncoded = ODataQueryBuilder().entity("People").search(Search("Name")).encode()
89 | print(urlEncoded)
90 | ```
91 |
92 | ## Requirements
93 |
94 | **v1.0.0**
95 | It is designed in Swift 5 and supports iOS, macOS, watchOS, tvOS
96 |
97 | ### CocoaPods
98 |
99 | ODataSwift is available through [CocoaPods](http://cocoapods.org). To install
100 | it, simply add the following lines to your Podfile:
101 |
102 | ```ruby
103 | use_frameworks!
104 | pod 'ODataSwift'
105 | ```
106 | ### Swift Package Manager
107 |
108 | ODataSwift is also available through [Swift Package Manager](https://github.com/apple/swift-package-manager/).
109 |
110 | #### Xcode
111 |
112 | Select `File > Swift Packages > Add Package Dependency...`,
113 | add `https://github.com/developer-celusion/ODataSwift.git`
114 |
115 | [comment]: <> (
)
116 |
117 | #### CLI
118 |
119 | First, create `Package.swift` that its package declaration includes:
120 |
121 | ```swift
122 | // swift-tools-version:5.0
123 | import PackageDescription
124 |
125 | let package = Package(
126 | name: "MyLibrary",
127 | products: [
128 | .library(name: "MyLibrary", targets: ["MyLibrary"]),
129 | ],
130 | dependencies: [
131 | .package(url: "https://github.com/developer-celusion/ODataSwift.git", from: "1.0.0"),
132 | ],
133 | targets: [
134 | .target(name: "MyLibrary", dependencies: ["ODataSwift"]),
135 | ]
136 | )
137 | ```
138 |
139 | Then, type
140 |
141 | ```shell
142 | $ swift build
143 | ```
144 |
145 | ### To manually add to your project
146 |
147 | 1. Add `Lib/ODataSwift.xcodeproj` to your project
148 | 2. Link `ODataSwift.framework` with your target
149 | 3. Add `Copy Files Build Phase` to include the framework to your application bundle
150 |
151 | _See [iOS Example Project](https://github.com/developer-celusion/ODataSwift/tree/master/Examples/Example-iOS) as reference._
152 |
153 | [comment]: <> (
)
154 |
155 | ## Author
156 |
157 | Swapnil Nandgave, developer@celusion.com
158 |
159 | ## License
160 |
161 | ODataSwift is available under the MIT license. See the LICENSE file for more info.
162 |
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/Count.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Count.swift
3 | //
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | //
7 |
8 | /*
9 | Count is system query option allows clients to request a count of matching resources included with the resources in the response
10 | There are 3 options available
11 | 1. $count in URL - e.g serviceRoot/People/$count
12 | 2. $count in resource response - e.g serviceRoot/People?$count=true
13 | 3. $inlinecount in resource response - serviceRoot/People?$inlinecount=
14 | */
15 |
16 | import Foundation
17 |
18 | /**
19 | # URLCount
20 | Count is system query option allows clients to request a count of matching resources included with the url
21 | e.g `serviceRoot/People?$count=true`
22 | ~~~
23 | ODataQueryBuilder().entity("People").onlyCount().build()
24 | ~~~
25 | - Returns: A URL Count instance which will append in OData URL
26 | */
27 |
28 | public class URLCount: QueryConvertible {
29 |
30 | private var expression = QueryOption.urlCount.queryText
31 |
32 | public var queryText: String {
33 | return expression
34 | }
35 |
36 | }
37 |
38 | /**
39 | # Count
40 | Count is system query option allows clients to request a count of matching resources included with the resources in the response
41 | e.g `serviceRoot/People?$count=true`
42 | ~~~
43 | ODataQueryBuilder().entity("People").withCount().build()
44 | ~~~
45 | - Returns: A Count instance which will include in OData Response
46 | */
47 |
48 | public class Count: QueryConvertible {
49 |
50 | private var expression = QueryOption.count.queryText
51 |
52 | public var queryText: String {
53 | return expression
54 | }
55 |
56 | }
57 |
58 | /**
59 | # InlineCount
60 | Count is system query option allows clients to request a count of matching resources included with the resources in the response
61 | e.g `serviceRoot/People?$inlinecount=name`
62 |
63 | ~~~
64 | ODataQueryBuilder().entity("People").inlineCount("Name").build()
65 | ~~~
66 |
67 | - Parameter property: Property of entity which is to be inlined for count
68 | - Returns: A InlineCount instance which will include in OData Response
69 | */
70 |
71 | public class InlineCount: QueryConvertible {
72 |
73 | private var expression = QueryOption.inlineCount.queryText
74 |
75 | private var property: String
76 |
77 | /// Property of entity
78 | public init(_ property: Any) {
79 | self.property = String(describing: property)
80 | }
81 |
82 | public var queryText: String {
83 | return self.expression + self.property
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/DateTime.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by Swapnil Nandgave on 06/01/20.
6 | //
7 |
8 | import Foundation
9 |
10 | /**
11 | # DateTime
12 | Enum declaration for OData DateTime functions
13 | */
14 | public enum DateTime:String, QueryConvertible {
15 | /// Compares with current date and time on OData server
16 | case now = "now()"
17 |
18 | /// It returns OData mindatetime functions
19 | case mindatetime = "mindatetime()"
20 |
21 | public var queryText: String {
22 | return self.rawValue
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/Error.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Error.swift
3 | //
4 | //
5 | // Created by Swapnil Nandgave on 09/01/20.
6 | //
7 |
8 | import Foundation
9 |
10 | public enum ODataError: Error {
11 |
12 | case urlNotSet
13 |
14 | }
15 |
16 | extension ODataError: LocalizedError {
17 |
18 | public var errorDescription: String? {
19 | switch self {
20 | case .urlNotSet:
21 | return "OData Url is not set. Use ODataQueryBuilder.configure method to set url"
22 | default:
23 | return ""
24 | }
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/Expand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Expand.swift
3 | //
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | //
7 |
8 | import Foundation
9 |
10 | /**
11 | # Expand
12 | The $expand system query option specifies the related resources to be included in line with retrieved resources.
13 | e.g The request below returns people with navigation property Friends of a Person
14 |
15 | ~~~
16 | serviceRoot/People('keithpinckney')?$expand=Friends
17 | ~~~
18 |
19 | [See Tutorial](https://www.odata.org/getting-started/basic-tutorial/#expand)
20 |
21 | */
22 |
23 | public class Expand: QueryConvertible {
24 |
25 | /// Navigational Properties
26 | private var properties = [String]()
27 |
28 | /// Filter block within expand
29 | private var filter: FilterExp?
30 |
31 | /// Select odata properties
32 | private var selects = [String]()
33 |
34 | /// Nested Expand
35 | private var expand: Expand?
36 |
37 | /**
38 | Initializes new Expand with provided navigational property or properties
39 | - Parameter property: Navigational property Name
40 | */
41 |
42 | public init(_ property: String) {
43 | self.properties = [property]
44 | }
45 |
46 | /**
47 | Initializes new Expand with provided navigational property or properties
48 | - Parameter properties: Navigational property Names
49 | */
50 | public init(_ properties: [String]) {
51 | self.properties = properties
52 | }
53 |
54 | /**
55 | Append new filter
56 |
57 | ~~~
58 | $expand=NavProperty($filter=name eq 'martin')
59 | ~~~
60 |
61 | - Parameter filter: instance of filter class
62 | */
63 | public func filter(_ filter: FilterExp)-> Self {
64 | self.filter = filter
65 | return self
66 | }
67 |
68 | /**
69 | Append new select
70 |
71 | ~~~
72 | $expand=NavProperty($select=Name)
73 | ~~~
74 |
75 | - Parameter select: $select property name of string type
76 | */
77 | public func select(_ select: String)-> Self {
78 | return self.selects([select])
79 | }
80 |
81 | /**
82 | Append new select
83 |
84 | ~~~
85 | $expand=NavProperty($select=Name,Mobile)
86 | ~~~
87 |
88 | - Parameter selects: $select property name of String data type
89 | */
90 | public func selects(_ selects: [String])-> Self {
91 | self.selects = selects
92 | return self
93 | }
94 |
95 | /**
96 | Append nested expand
97 |
98 | ~~~
99 | $expand=NavProperty($expand=NestedExpand)
100 | ~~~
101 |
102 | - Parameter expand: $expand inside expand
103 | */
104 | public func expand(_ expand:Expand)-> Self {
105 | self.expand = expand
106 | return self
107 | }
108 |
109 | public var queryText: String {
110 | var temp = "";
111 | temp += properties.joined(separator: ",")
112 | var part = "";
113 | if(selects.count > 0) {
114 | part += QueryOption.select.queryText
115 | part += selects.joined(separator: ",")
116 | }
117 | if let filter = self.filter {
118 | requestPart(part: &part)
119 | part += QueryOption.filter.queryText
120 | part += filter.queryText
121 | }
122 | if let expand = self.expand {
123 | requestPart(part: &part)
124 | part += QueryOption.expand.queryText
125 | part += expand.queryText
126 | }
127 | if(part.count > 0) {
128 | temp += "(" + part + ")"
129 | }
130 | return temp
131 | }
132 |
133 | private func requestPart(part: inout String) {
134 | if(part.count > 0) {
135 | part += ";"
136 | }
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/Filter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FilterExp.swift
3 | //
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Mode to combine two expressions
11 | public enum BasicOperator: String, QueryConvertible {
12 |
13 | case none = ""
14 |
15 | /**
16 | Add two odata expressions or filter blocks by basic and
17 |
18 | ~~~
19 | $filter=Name eq 'martin' and usercode eq '0000'
20 | ~~~
21 | */
22 | case and = " and "
23 |
24 | /**
25 | Add two odata expressions or filter blocks by basic or
26 |
27 | ~~~
28 | $filter=Name eq 'martin' or usercode eq '0000'
29 | ~~~
30 | */
31 | case or = " or "
32 |
33 | public var queryText: String {
34 | return self.rawValue
35 | }
36 |
37 | }
38 |
39 | /// OData predicate to create expression
40 | public enum Predicate: String, QueryConvertible {
41 |
42 | /**
43 | Create expression with Equal **eq**
44 |
45 | ~~~
46 | $filter=Name eq 'martin'
47 | ~~~
48 | */
49 | case eq = " eq "
50 |
51 | /**
52 | Create expression with Less Than **lt**
53 |
54 | ~~~
55 | $filter=Age lt 65
56 | ~~~
57 | */
58 | case lt = " lt "
59 |
60 | /**
61 | Create expression with Greater than **gt**
62 |
63 | ~~~
64 | $filter=Age gt 18
65 | ~~~
66 | */
67 | case gt = " gt "
68 |
69 | /**
70 | Create expression with Less than equal to **le**
71 |
72 | ~~~
73 | $filter=Age le 65
74 | ~~~
75 | */
76 | case le = " le "
77 |
78 | /**
79 | Create expression with Greater than equal to **ge**
80 |
81 | ~~~
82 | $filter=Age ge 18
83 | ~~~
84 | */
85 | case ge = " ge "
86 |
87 | /**
88 | Create expression with contains operator **contains**
89 |
90 | ~~~
91 | $filter=contains('name','marti')
92 | ~~~
93 | */
94 | case contains = "contains"
95 |
96 | /**
97 | Create expression with endswith operator **endswith**
98 |
99 | ~~~
100 | $filter=endswith('name','marti')
101 | ~~~
102 | */
103 | case endswith = "endswith"
104 |
105 | /**
106 | Create expression with startswith operator **startswith**
107 |
108 | ~~~
109 | $filter=startswith('name','marti')
110 | ~~~
111 | */
112 | case startswith = "startswith"
113 |
114 | public var queryText: String {
115 | return self.rawValue
116 | }
117 |
118 | public var expFirst: Bool {
119 | return (self == .contains || self == .endswith || self == .startswith)
120 | }
121 |
122 | }
123 |
124 | /**
125 | # FilterExp
126 | The $filter system query option allows clients to filter a collection of resources that are addressed by a request URL. The expression specified with $filter is evaluated for each resource in the collection, and only items where the expression evaluates to true are included in the response.
127 |
128 | ~~~
129 | serviceRoot/People?$filter=FirstName eq 'Scott'
130 | ~~~
131 |
132 | [See Tutorial](https://www.odata.org/getting-started/basic-tutorial/#filter)
133 |
134 | */
135 | public class FilterExp: QueryConvertible {
136 |
137 | /// Predicate property name
138 | private var property:String
139 |
140 | /// Predicate
141 | private var filterOption: Predicate?
142 |
143 | /// Value of predicate expression
144 | private var _value:String?
145 |
146 | // MARK: Concating Expression
147 | private var conjection: BasicOperator = .none
148 |
149 | /// Nested Grouped filter which does come under **( )**
150 | private var expression: FilterExp? = nil
151 |
152 | /// Nested Grouped filters which does come under **( )**
153 | private var expressions: [FilterExp] = [FilterExp]()
154 |
155 | /// Initiazes with entity property
156 | public init(_ property:String) {
157 | self.property = property
158 | }
159 |
160 | /// Initializes with property function
161 | public init(_ propertyFunc:PropertyFunc) {
162 | self.property = propertyFunc.queryText
163 | }
164 |
165 | /**
166 | Any value data type. It add ' when type is String otherwise set directly
167 | e.g age eq 10 and name eq 'martin'
168 | */
169 | public func value(_ value: Any)-> Self {
170 | if value is String {
171 | self._value = "'" + String(describing: value) + "'"
172 | } else {
173 | self._value = String(describing: value)
174 | }
175 | return self
176 | }
177 |
178 | /// Set Date time function as value
179 | public func date(_ dateTime:DateTime)->Self {
180 | self._value = dateTime.queryText
181 | return self
182 | }
183 |
184 | /**
185 | Set formatted date string as value by calling this function. Convert date to string by using DateFormatter and pass as argument
186 | e.g $filter=CreatedOn eq 2020-12-12T10:10:10
187 | */
188 | public func date(_ value: String)-> Self {
189 | self._value = String(describing: value)
190 | return self
191 | }
192 |
193 | /// Greater than equal to predicate
194 | public func ge()->Self {
195 | self.filterOption = .ge
196 | return self
197 | }
198 |
199 | /// less than equal to predicate
200 | public func le()->Self {
201 | self.filterOption = .le
202 | return self
203 | }
204 |
205 | /// greater than predicate
206 | public func gt()->Self {
207 | self.filterOption = .gt
208 | return self
209 | }
210 |
211 | /// equal to predicate
212 | public func eq()->Self {
213 | self.filterOption = .eq
214 | return self
215 | }
216 |
217 | /// less than predicate
218 | public func lt()->Self {
219 | self.filterOption = .lt
220 | return self
221 | }
222 |
223 | /// contains predicate
224 | public func contains()->Self {
225 | self.filterOption = .contains
226 | return self
227 | }
228 |
229 | /// endswith predicate
230 | public func endswith()->Self {
231 | self.filterOption = .endswith
232 | return self
233 | }
234 |
235 | /// startswith predicate
236 | public func startswith()->Self {
237 | self.filterOption = .startswith
238 | return self
239 | }
240 |
241 | /**
242 | Add filter by Basic Operator **AND**
243 | e.g $filter=Age lt 65 and Name eq 'martin'
244 | */
245 | public func and(_ expression: FilterExp)->Self {
246 | self.conjection = .and
247 | self.expression = expression
248 | return self
249 | }
250 |
251 | /**
252 | Add filters by Basic Operator **AND**. It will group the array into bracket
253 | e.g $filter=Age lt 65 and (Name eq 'martin')
254 | */
255 | public func and(_ expressions: [FilterExp])->Self {
256 | self.conjection = .and
257 | self.expressions = expressions
258 | return self
259 | }
260 |
261 | /**
262 | Add filter by Basic Operator **OR**
263 | e.g $filter=Age lt 65 or Name eq 'martin'
264 | */
265 | public func or(_ expression: FilterExp)->Self {
266 | self.conjection = .or
267 | self.expression = expression
268 | return self
269 | }
270 |
271 | /**
272 | Add filters by Basic Operator **OR**. It will group the array into bracket
273 | e.g $filter=Age lt 65 or (Name eq 'martin')
274 | */
275 | public func or(_ expressions: [FilterExp])->Self {
276 | self.conjection = .or
277 | self.expressions = expressions
278 | return self
279 | }
280 |
281 | public var queryText: String {
282 | var temp = ""
283 | if let filterOption = filterOption {
284 | if filterOption.expFirst {
285 | temp += filterOption.queryText
286 | temp += "(" + property + "," + (_value ?? "") + ")"
287 | } else {
288 | temp += property
289 | temp += filterOption.queryText
290 | temp += _value ?? ""
291 | }
292 | if let expression = expression {
293 | temp += conjection.queryText + expression.queryText
294 | }
295 | if self.expressions.count > 0 {
296 | temp += conjection.queryText + " ("
297 | for expression in expressions {
298 | temp += expression.queryText
299 | }
300 | temp += ")"
301 | }
302 | }
303 | return temp
304 | }
305 |
306 | }
307 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/Funtion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by Swapnil Nandgave on 06/01/20.
6 | //
7 |
8 | import Foundation
9 |
10 | /// OData Functions
11 | public enum Function: String, QueryConvertible {
12 |
13 | case length = "length"
14 | case tolower = "tolower"
15 | case toupper = "toupper"
16 | case trim = "trim"
17 | case indexof = "indexof"
18 | case substring = "substring"
19 | case year = "year"
20 | case month = "month"
21 | case day = "day"
22 | case hour = "hour"
23 | case minute = "minute"
24 | case second = "second"
25 | case fractionalseconds = "fractionalseconds"
26 | case totaloffsetminutes = "totaloffsetminutes"
27 |
28 | public var hasArgs: Bool {
29 | return (self == .indexof || self == .substring)
30 | }
31 |
32 | public var queryText: String {
33 | return self.rawValue
34 | }
35 |
36 | }
37 |
38 | /// Logicial OData operators used along with $filter. Adding Any / All support to the protocol will greatly improve the expressiveness of OData queries.
39 | public enum LogicalOperator: String, QueryConvertible {
40 |
41 | case any = "any"
42 | case all = "all"
43 |
44 | public var queryText: String {
45 | return "/" + self.rawValue
46 | }
47 |
48 | }
49 |
50 | /**
51 | Adding Any / All support to the protocol will greatly improve the expressiveness of OData queries.
52 |
53 | ~~~
54 | ~/Movies/?$filter=any(Name eq 'John Belushi')
55 | ~/Orders/?$filter=any(Product/Name eq 'kinect')
56 | ~~~
57 |
58 | */
59 | public class OperatorFunc: QueryConvertible {
60 |
61 | /// Property of operator like Name
62 | private var property: String
63 |
64 | /// All or Any
65 | private var propertyOps: LogicalOperator
66 |
67 | /// String presentation of Property Function. Use queryText or String(describing: ) to get the string presentation
68 | private var propertyFunc: String? = nil
69 |
70 | public init(_ property: String,_ propertyOps: LogicalOperator) {
71 | self.property = property
72 | self.propertyOps = propertyOps
73 | }
74 |
75 | public func add(_ propertyFunc: String)-> Self {
76 | self.propertyFunc = propertyFunc
77 | return self
78 | }
79 |
80 | public var queryText: String {
81 | var temp = property + propertyOps.queryText
82 | if let propertyFunc = self.propertyFunc {
83 | temp += "(" + propertyFunc + ")"
84 | }
85 | return temp
86 | }
87 |
88 | }
89 |
90 | /**
91 | It is the part of OperatorFunc to generate inclined property expression. e.g **Name eq 'John Belushi'**
92 |
93 | ~~~
94 | ~/Movies/?$filter=any(Name eq 'John Belushi')
95 | ~/Orders/?$filter=any(Product/Name eq 'kinect')
96 | ~~~
97 |
98 | */
99 | public class PropertyFunc: QueryConvertible, CustomStringConvertible {
100 |
101 | private var name: String
102 | private var function: Function
103 | private var _value: String? = nil
104 |
105 | public init(_ name:String,_ function: Function) {
106 | self.name = name
107 | self.function = function
108 | }
109 |
110 | public func value(_ value: Any)->Self {
111 | if value is String {
112 | self._value = "'" + String(describing: value) + "'"
113 | } else {
114 | self._value = String(describing: value)
115 | }
116 | return self
117 | }
118 |
119 | public var queryText: String {
120 | var temp = function.queryText
121 | temp += "(" + name
122 | if let value = self._value, function.hasArgs {
123 | temp += ", " + value
124 | }
125 | temp += ")"
126 | return temp
127 | }
128 |
129 | public var description: String {
130 | return queryText
131 | }
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/ODataQueryBuilder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ODataQueryBuilder.swift
3 | // ODataQueryBuilder
4 | //
5 | // Created by Celusion Technologies on 16/03/18.
6 | //
7 |
8 | import Foundation
9 |
10 | /**
11 | # ODataQueryBuilder
12 |
13 | OData (Open Data Protocol) is an ISO/IEC approved, OASIS standard that defines a set of best practices for building and consuming RESTful APIs. OData helps you focus on your business logic while building RESTful APIs without having to worry about the various approaches to define request and response headers, status codes, HTTP methods, URL conventions, media types, payload formats, query options, etc. OData also provides guidance for tracking changes, defining functions/actions for reusable procedures, and sending asynchronous/batch requests.
14 |
15 | OData RESTful APIs are easy to consume. The OData metadata, a machine-readable description of the data model of the APIs, enables the creation of powerful generic client proxies and tools.
16 |
17 | ODataQueryBuilder is utility class to generate OData Queries and providing almost all the operators and functions like $filter, $expand, $select, $search etc. You can build the oData query and execute
18 | on OData server to get required resource results
19 |
20 | [Basic Tutorial](https://www.odata.org/getting-started/basic-tutorial/)
21 |
22 | */
23 |
24 | public class ODataQueryBuilder: QueryConvertible {
25 |
26 | public typealias ODQueBuilder = ODataQueryBuilder
27 |
28 | private static var url: String? = nil
29 |
30 | private static let INVALID = -990
31 | private var entityName: String? = nil
32 | private var selects = [String]()
33 | private var filters = [FilterExp]()
34 | private var expands = [Expand]()
35 | private var orders = [Order]()
36 | private var search: Search? = nil
37 | private var urlCount: URLCount? = nil
38 | private var count: Count? = nil
39 | private var inlineCount: InlineCount? = nil
40 | private var skip : Int = INVALID
41 | private var top : Int = INVALID
42 | private var id = ""
43 | private var unboundFunc = ""
44 | private var boundFunc = ""
45 |
46 | private var skipMultiplier = -1;
47 | private var interval = ODataQueryBuilder.INVALID
48 |
49 | public static func configure(url: String) {
50 | ODataQueryBuilder.url = url
51 | }
52 |
53 | public init() {
54 | if Self.url == nil {
55 | fatalError(ODataError.urlNotSet.localizedDescription)
56 | }
57 | self.entityName = nil
58 | self.selects = [String]()
59 | self.filters = [FilterExp]()
60 | self.expands = [Expand]()
61 | self.orders = [Order]()
62 | self.urlCount = nil
63 | self.skip = Self.INVALID
64 | self.top = Self.INVALID
65 | self.id = ""
66 | }
67 |
68 | /// Append Entity e.g serviceRoot/People
69 | public func entity(_ value: String) -> Self {
70 | self.entityName = value
71 | return self
72 | }
73 |
74 | /**
75 | Append Select query option
76 |
77 | ~~~
78 | serviceRoot/People?$select=Name
79 | ~~~
80 |
81 | */
82 | public func select(_ value: String)-> Self {
83 | self.selects([value])
84 | }
85 |
86 | /**
87 | Append Select query option
88 |
89 | ~~~
90 | serviceRoot/People?$select=ID, Name
91 | ~~~
92 |
93 | */
94 | public func selects(_ values:[String]) -> Self {
95 | if(values.count > 0) {
96 | self.selects = values
97 | }
98 | return self
99 | }
100 |
101 | /**
102 | Append Filter query option
103 |
104 | ~~~
105 | serviceRoot/People?$filter=Name eq 'Martin'
106 | ~~~
107 |
108 | */
109 |
110 | public func filter(_ value: FilterExp)-> Self {
111 | self.filters = [value]
112 | return self
113 | }
114 |
115 | /**
116 | Append Filter query option
117 |
118 | ~~~
119 | serviceRoot/People?$search=Boise
120 | ~~~
121 |
122 | */
123 |
124 | public func search(_ value: Search)-> Self {
125 | self.search = value
126 | return self
127 | }
128 |
129 | /**
130 | Append Expand query option
131 |
132 | ~~~
133 | serviceRoot/People?$expand=Address
134 | ~~~
135 |
136 | */
137 |
138 | public func expand(_ value: Expand)-> Self {
139 | self.expands.append(value)
140 | return self
141 | }
142 |
143 | /**
144 | Append Expand query option
145 |
146 | ~~~
147 | serviceRoot/People?$expand=Address, ContactDetail
148 | ~~~
149 |
150 | */
151 |
152 | public func expands(_ values: [Expand])-> Self {
153 | if(values.count > 0) {
154 | self.expands.append(contentsOf: values);
155 | }
156 | return self
157 | }
158 |
159 | /**
160 | Append Order query option
161 |
162 | ~~~
163 | serviceRoot/People?$orderby=ID desc
164 | ~~~
165 |
166 | */
167 |
168 | public func order(_ value: Order)-> Self {
169 | return self.orders([value])
170 | }
171 |
172 | /**
173 | Append Order query option
174 |
175 | ~~~
176 | serviceRoot/People?$orderby=ID desc, name asc
177 | ~~~
178 |
179 | */
180 |
181 | public func orders(_ values: [Order])-> Self {
182 | if(values.count > 0) {
183 | self.orders = values
184 | }
185 | return self
186 | }
187 |
188 | /**
189 | Append Skip query option
190 |
191 | ~~~
192 | serviceRoot/People?$skip=10
193 | ~~~
194 |
195 | */
196 |
197 | public func skip(_ value: Int)-> Self {
198 | self.skip = value
199 | return self
200 | }
201 |
202 | /**
203 | Append Skip query option
204 |
205 | ~~~
206 | serviceRoot/People?$top=10
207 | ~~~
208 |
209 | */
210 |
211 | public func top(_ value: Int)-> Self {
212 | self.top = value
213 | return self
214 | }
215 |
216 | /**
217 | Append ID query option. ID is Primary key of Entity
218 |
219 | ~~~
220 | serviceRoot/People('Martin')
221 | serviceRoot/Address(10)
222 | ~~~
223 |
224 | */
225 |
226 | public func id(_ id:Any,_ segmentProperty: String? = nil)-> Self {
227 | if let str = id as? String {
228 | self.id = "('"+String(describing:str)+"')";
229 | } else {
230 | self.id = "("+String(describing: id)+")"
231 | }
232 | if let segmentProperty = segmentProperty {
233 | if !segmentProperty.hasPrefix("/") {
234 | self.id += "/"
235 | }
236 | self.id += segmentProperty
237 | }
238 | return self
239 | }
240 |
241 | /**
242 | Append bound OData function e.g Need to pass **Microsoft.OData.SampleService.Models.TripPin.GetFavoriteAirline()** along with /
243 |
244 | ~~~
245 | serviceRoot/People('russellwhyte')/Microsoft.OData.SampleService.Models.TripPin.GetFavoriteAirline()
246 | ~~~
247 |
248 | */
249 | public func boundFunction(_ name: String)->Self {
250 | self.boundFunc = name
251 | return self
252 | }
253 |
254 | /**
255 | Append unbound OData function. e.g Need to pass **GetNearestAirport(lat = 33, lon = -118)** along with /
256 |
257 | ~~~
258 | serviceRoot/GetNearestAirport(lat = 33, lon = -118)
259 | ~~~
260 |
261 | */
262 | public func unboundFunction(_ name: String)->Self {
263 | self.unboundFunc = name
264 | return self
265 | }
266 |
267 | /// Appends /$count in OData Query URL
268 | public func onlyCount()-> Self {
269 | self.urlCount = URLCount()
270 | return self
271 | }
272 |
273 | /// Appends $count=true as params
274 | public func withCount()-> Self {
275 | self.count = Count()
276 | return self
277 | }
278 |
279 | /// Appends $inlinecount=name as params
280 | public func inlineCount(_ property: String)-> Self {
281 | self.inlineCount = InlineCount(property)
282 | return self
283 | }
284 |
285 | /// Forms url and return in plain String. .encode will return encoded url which you can use in network calls
286 | public func build()-> String {
287 | var temp = queryUrlPart()
288 | if self.unboundFunc.count > 0 {
289 | temp += self.unboundFunc
290 | }
291 | temp += idPart()
292 | if self.boundFunc.count > 0 {
293 | temp += self.boundFunc
294 | }
295 | if urlCount != nil {
296 | temp += urlCount!.queryText
297 | }
298 | if(isExp()) {
299 | temp += expPart()
300 | temp += userQueryPart()
301 | }
302 | return temp
303 | }
304 |
305 | /// Returns url in plain text
306 | public var queryText: String {
307 | return build()
308 | }
309 |
310 | /// Returns encoded url which can be used in Network calls
311 | public func encode()->String {
312 | var temp = build()
313 | temp = temp.replacingOccurrences(of: " ", with: "%20").replacingOccurrences(of: "+", with: "%2B")
314 | return temp
315 | }
316 |
317 | /// Use this method to initialize pagination
318 | public func paginate(interval: Int)->Self {
319 | skipMultiplier = -1;
320 | self.interval = interval
321 | return self
322 | }
323 |
324 | /// Use this method to get next page and call build or encode to get next page OData URL
325 | public func nextPage() {
326 | if(interval != Self.INVALID) {
327 | skipMultiplier += 1
328 | self.top = self.interval
329 | self.skip = skipMultiplier * self.interval
330 | } else {
331 | print("Interval is missing")
332 | }
333 | }
334 |
335 | private func queryUrlPart()-> String {
336 | if let base = Self.url, let entity = entityName {
337 | var temp = base
338 | temp += temp.hasSuffix("/") ? "" : "/"
339 | temp += entity
340 | return temp
341 | } else {
342 | return ""
343 | }
344 | }
345 |
346 | private func idPart()-> String {
347 | return id
348 | }
349 |
350 | private func expPart() -> String {
351 | if(isExp()) {
352 | return "?"
353 | } else {
354 | return ""
355 | }
356 | }
357 |
358 | private func userQueryPart() -> String {
359 | var temp = "";
360 | if let count = self.count {
361 | temp += count.queryText
362 | }
363 | if let inlineCount = inlineCount {
364 | temp += inlineCount.queryText
365 | }
366 | if let search = self.search {
367 | temp += search.queryText
368 | }
369 | if(selects.count > 0) {
370 | temp += QueryOption.select.rawValue
371 | temp += selects.joined(separator: ",")
372 | }
373 | if(filters.count > 0) {
374 | requestPart(part: &temp)
375 | temp += QueryOption.filter.rawValue
376 | filters.forEach { item in
377 | temp += item.queryText
378 | }
379 | }
380 | if(expands.count > 0) {
381 | requestPart(part: &temp)
382 | temp += QueryOption.expand.rawValue
383 | var list = [String]()
384 | expands.forEach { order in
385 | list.append(order.queryText)
386 | }
387 | temp += list.joined(separator: ",")
388 | }
389 | if(orders.count > 0) {
390 | requestPart(part: &temp)
391 | temp += QueryOption.order.rawValue
392 | var list = [String]()
393 | orders.forEach { order in
394 | list.append(order.queryText)
395 | }
396 | temp += list.joined(separator: ",")
397 | }
398 | if(skip != Self.INVALID) {
399 | requestPart(part: &temp)
400 | temp += QueryOption.skip.rawValue
401 | temp += String(skip)
402 | }
403 | if(top != Self.INVALID) {
404 | requestPart(part: &temp)
405 | temp += QueryOption.top.rawValue
406 | temp += String(top)
407 | }
408 | return temp
409 | }
410 |
411 | private func requestPart(part : inout String) {
412 | if(part.count > 0) {
413 | part += "&"
414 | }
415 | }
416 |
417 | private func isExp() -> Bool {
418 | if(selects.count > 0 || filters.count > 0 || search != nil || expands.count > 0 || orders.count > 0 || skip != Self.INVALID || top != Self.INVALID || count != nil || inlineCount != nil) {
419 | return true
420 | } else {
421 | return false
422 | }
423 | }
424 |
425 | }
426 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/Order.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Order.swift
3 | //
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | //
7 |
8 | import Foundation
9 |
10 | public enum OrderType: String, QueryConvertible {
11 |
12 | /// ascending order
13 | case asc = "asc"
14 |
15 | /// descending order
16 | case desc = "desc"
17 |
18 | public var queryText: String {
19 | return self.rawValue
20 | }
21 |
22 | }
23 |
24 | /**
25 | The $orderby system query option allows clients to request resources in either ascending order using asc or descending order using desc. If asc or desc not specified, then the resources will be ordered in ascending order. The request below orders Trips on property EndsAt in descending order.
26 |
27 | ~~~
28 | serviceRoot/People('scottketchum')/Trips?$orderby=EndsAt desc
29 | ~~~
30 | */
31 |
32 | public class Order: QueryConvertible {
33 |
34 | private var property: String
35 | private var orderType = OrderType.asc
36 |
37 | public convenience init(_ property:String) {
38 | self.init(property,orderType: .asc)
39 | }
40 |
41 | public init(_ property:String, orderType:OrderType) {
42 | self.property = property
43 | self.orderType = orderType
44 | }
45 |
46 | public var queryText: String {
47 | var temp = property
48 | temp += " "
49 | temp += String(describing: orderType)
50 | return temp
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/QueryConvertible.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QueryConvertible.swift
3 | //
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | //
7 |
8 | import Foundation
9 |
10 | /// OData Query Representation
11 | public protocol QueryConvertible {
12 |
13 | var queryText: String { get }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/QueryOption.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QueryOption.swift
3 | //
4 | //
5 | // Created by Swapnil Nandgave on 02/01/20.
6 | //
7 |
8 | import Foundation
9 |
10 | /**
11 | OData supports various kinds of query options for querying data. This section will help you go through the common scenarios for these query options.
12 | */
13 |
14 | public enum QueryOption: String, QueryConvertible {
15 |
16 | case select = "$select="
17 | case filter = "$filter="
18 | case expand = "$expand="
19 | case order = "$orderby="
20 | case skip = "$skip="
21 | case top = "$top="
22 | case urlCount = "/$count"
23 | case count = "$count=true"
24 | case inlineCount = "$inlinecount="
25 | case search = "$search="
26 |
27 | public var queryText: String {
28 | return self.rawValue
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/ODataSwift/Search.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by Swapnil Nandgave on 06/01/20.
6 | //
7 |
8 | import Foundation
9 |
10 | /**
11 | The $search system query option restricts the result to include only those entities matching the specified search expression. The definition of what it means to match is dependent upon the implementation. The request below get all People who has 'Boise' in their contents.
12 |
13 | ~~~
14 | serviceRoot/People?$search=Boise
15 | ~~~
16 |
17 | */
18 |
19 | public class Search: QueryConvertible {
20 |
21 | private var expression = QueryOption.search.queryText
22 |
23 | private var property: String
24 |
25 | public init(_ property: String) {
26 | self.property = property
27 | }
28 |
29 | public var queryText: String {
30 | return self.expression + self.property
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import ODataSwiftTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += ODataSwiftTests.allTests()
7 | XCTMain(tests)
8 |
--------------------------------------------------------------------------------
/Tests/ODataSwiftTests/ODataSwiftTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import ODataSwift
3 |
4 | final class ODataSwiftTests: XCTestCase {
5 | func testExample() {
6 | // This is an example of a functional test case.
7 | // Use XCTAssert and related functions to verify your tests produce the correct
8 | // results.
9 | XCTAssertEqual("Hello, World!", "Hello, World!")
10 | }
11 |
12 | static var allTests = [
13 | ("testExample", testExample),
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/Tests/ODataSwiftTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | #if !canImport(ObjectiveC)
4 | public func allTests() -> [XCTestCaseEntry] {
5 | return [
6 | testCase(ODataSwiftTests.allTests),
7 | ]
8 | }
9 | #endif
10 |
--------------------------------------------------------------------------------