From f1b97a4b6662a789dfc2aa58e6bf72e4952dab7f Mon Sep 17 00:00:00 2001 From: skyflow-bharti Date: Sun, 8 Mar 2026 11:44:59 +0530 Subject: [PATCH 1/2] SK-2592-readme-and-sample-changes-for-updating-data-through-elements-in-ios-sdk --- README.md | 463 ++++++++++- Samples/UpdateDataUsingElements/Podfile | 29 + .../project.pbxproj | 756 ++++++++++++++++++ .../contents.xcworkspacedata | 10 + .../UpdateDataUsingElements/AppDelegate.swift | 36 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 35 + .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 + .../Base.lproj/Main.storyboard | 24 + .../ExampleAPICallback.swift | 48 ++ .../ExampleTokenProvider.swift | 31 + .../UpdateDataUsingElements/Info.plist | 25 + .../ResponseStructs.swift | 24 + .../SceneDelegate.swift | 52 ++ .../ViewController.swift | 183 +++++ .../UpdateDataUsingElementsTests.swift | 36 + .../UpdateDataUsingElementsUITests.swift | 41 + ...eDataUsingElementsUITestsLaunchTests.swift | 33 + 19 files changed, 1858 insertions(+), 10 deletions(-) create mode 100644 Samples/UpdateDataUsingElements/Podfile create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements.xcodeproj/project.pbxproj create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements.xcworkspace/contents.xcworkspacedata create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/AppDelegate.swift create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/Contents.json create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/Base.lproj/LaunchScreen.storyboard create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/Base.lproj/Main.storyboard create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/ExampleAPICallback.swift create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/ExampleTokenProvider.swift create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/Info.plist create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/ResponseStructs.swift create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/SceneDelegate.swift create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElements/ViewController.swift create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElementsTests/UpdateDataUsingElementsTests.swift create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElementsUITests/UpdateDataUsingElementsUITests.swift create mode 100644 Samples/UpdateDataUsingElements/UpdateDataUsingElementsUITests/UpdateDataUsingElementsUITestsLaunchTests.swift diff --git a/README.md b/README.md index a51b2eda..2f68ddbe 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ For `env` parameter, there are 2 accepted values in Skyflow.Env # Securely collecting data client-side - [**Inserting data into the vault**](#insert-data-into-the-vault) - [**Using Skyflow Elements to collect data**](#using-skyflow-elements-to-collect-data) +- [**Using Skyflow Elements to update data**](#using-skyflow-elements-to-update-data) - [**Using validations on Collect Elements**](#validations) - [**Event Listener on Collect Elements**](#event-listener-on-collect-elements) - [**UI Error for Collect Elements**](#ui-error-for-collect-elements) @@ -465,6 +466,7 @@ let insertCallback = InsertCallback() container?.collect(callback: insertCallback, options: options) ``` + ### Collect data with Skyflow Elements #### Collect call example: @@ -538,6 +540,7 @@ let insertCallback = InsertCallback() // Call collect method on CollectContainer. container?.collect(callback: insertCallback, options: collectOptions) ``` + #### Skyflow returns tokens for the record you just inserted: ``` { @@ -554,8 +557,196 @@ container?.collect(callback: insertCallback, options: collectOptions) }] } ``` + +## Using Skyflow Elements to update data +You can update the data in a vault with Skyflow Elements. Use the following steps to securely update data. + +### Step 1: Create a container + +First create a **container** for the form elements using the ```skyflowClient.container(type: Skyflow.ContainerType)``` method as show below + +```swift +let container = skyflowClient.container(type: Skyflow.ContainerType.COLLECT) +``` + +### Step 2: Create a collect Element +To create a collect Element, we must first construct a Skyflow.CollectElementInput object defined as shown below: + +```swift +let collectElementInput = Skyflow.CollectElementInput( + table: String, // optional, the table this data belongs to + column: String, // optional, the column into which this data should be inserted + inputStyles: Skyflow.Styles, // optional styles that should be applied to the form element + labelStyles: Skyflow.Styles, // optional styles that will be applied to the label of the collect element + errorTextStyles: Skyflow.Styles, // optional styles that will be applied to the errorText of the collect element + label: String, // optional label for the form element + placeholder: String, // optional placeholder for the form element + altText: String, // (DEPRECATED) optional that acts as an initial value for the collect element + validations: ValidationSet, // optional set of validations for the input element + type: Skyflow.ElementType, // Skyflow.ElementType enum + skyflowID: String, // The skyflow_id of the record to be updated. +) +``` + +The `table` and `column` fields indicate which table and column in the vault the Element corresponds to. + +**Note**: +- Use dot delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`) +- `table` and `column` are optional only if the element is being used in invokeConnection() + +Along with `CollectElementInput`, you can define other options in the `CollectElementOptions` object which is described below. + +```swift +Skyflow.CollectElementOptions( + required: Boolean, // Indicates whether the field is marked as required. Defaults to 'false' + enableCardIcon: Boolean, // Indicates whether card icon should be enabled (only for CARD_NUMBER inputs) + format: String, // Format for the element + translation: [Character: String] // Indicates the allowed data type value for format. + enableCopy: Boolean, // Indicates whether to enable the copy icon in collect elements to copy text to clipboard. Defaults to 'false' + cardMetaData: [String: [Skyflow.CardType]] // Optional, metadata to control card number element behavior. (only applicable for CARD_NUMBER ElementType). +) +``` + +### Step 3: Mount Elements to the Screen + +To specify where the Elements will be rendered on the screen, create a parent UIView (like UIStackView, etc) and you can add it as a subview programmatically. + +```swift +let stackView = UIStackView() +stackView.addArrangedSubview(element) +``` + +The Skyflow Element is an implementation of the UIView so it can be used/mounted similarly. Alternatively, you can use the `unmount` method to reset any collect element to it's initial state + +``` swift +func clearFieldsOnSubmit(_ elements: [TextField]) { + // resets all elements in the array + for element in elements { + element.unmount() + } +} +``` + +### Step 4 : Update data from Elements +When the form is ready to submit, call the `collect(options?)` method on the container object. The `options` parameter takes a object of optional parameters as shown below: +- `tokens`: indicates whether tokens for the collected data should be returned or not. Defaults to 'true' +- `additionalFields`: Non-PCI elements data to update or insert into the vault which should be in the records object format. +- `upsert`: To support upsert operations while collecting data from Skyflow elements, pass the table and column marked as unique in the table. + +```swift +// Non-PCI records +let nonPCIRecords = ["table": "persons", "fields": [["gender": "MALE", "skyflowID": "value"]]] +// Upsert +let upsertOptions = [["table": "cards", "column": "cardNumber"]] as [[String : Any]] +// Send the non-PCI records as additionalFields of InsertOptions (optional) and apply upsert using `upsert` field of InsertOptions (optional) + +let options = Skyflow.CollectOptions(tokens: true, additionalFields: nonPCIRecords) + +//Custom callback - implementation of Skyflow.callback +let insertCallback = InsertCallback() +container?.collect(callback: insertCallback, options: options) +``` + +**Note:** `skyflowID` is required if you want to update the data. If `skyflowID` isn't specified, the `collect(options?)` method creates a new record in the vault. + +### End to end example of updating data with Skyflow Elements +```swift + +//Initialize skyflow configuration. +let config = Skyflow.Configuration(vaultID: VAULT_ID, vaultURL: VAULT_URL, tokenProvider: demoTokenProvider) + +//Initialize skyflow client. +let skyflowClient = Skyflow.initialize(config) + +//Create a CollectContainer. +let container = skyflowClient.container(type: Skyflow.ContainerType.COLLECT) + +//Create Skyflow.Styles with individual Skyflow.Style variants. +let baseStyle = Skyflow.Style(borderColor: UIColor.blue) +let baseTextStyle = Skyflow.Style(textColor: UIColor.black) +let completeStyle = Skyflow.Style(borderColor: UIColor.green) +let focusTextStyle = Skyflow.Style(textColor: UIColor.red) +let inputStyles = Skyflow.Styles(base: baseStyle, complete: completeStyle) +let labelStyles = Skyflow.Styles(base: baseTextStyle, focus: focusTextStyle) +let errorTextStyles = Skyflow.Styles(base: baseTextStyle) + +let iconStyles = Skyflow.Styles(base: Style(cardIconAlignment: .left)) + +// Create a CollectElementInput. +let input = Skyflow.CollectElementInput( + table: "cards", + column: "cardNumber", + inputStyles: inputStyles, + labelStyles: labelStyles, + errorTextStyles: errorTextStyles, + iconStyles: iconStyles, + label: "card number", + placeholder: "card number", + type: Skyflow.ElementType.CARD_NUMBER, + skyflowID: "431eaa6c-5c15-4513-aa15-29f50babe882" +) + +// Create an option to require the element. +let requiredOption = Skyflow.CollectElementOptions(required: true, enableCopy: true) + +// Create a Collect Element from the Collect Container. +let skyflowElement = container?.create(input: input, options: requiredOption) + +// Can interact with this object as a normal UIView Object and add to View + +// Non-PCI records +let nonPCIRecords = [["table": "persons", "fields": ["gender": "MALE"]], ["table": "cards", "fields": ["first_name": "Joe"], "skyflowID": "431eaa6c-5c15-4513-aa15-29f50babe882"]] + + //Upsert options + let upsertOptions = [["table": "cards", "column": "cardNumber"]] as [[String : Any]] + +// Send the Non-PCI records as additionalFields of CollectOptions (optional) and apply upsert using optional field `upsert` of CollectOptions. +let collectOptions = Skyflow.CollectOptions(tokens: true, additionalFields: nonPCIRecords, upsert: upsertOptions) + + +//Implement a custom Skyflow.Callback to call on Insertion success/failure. +public class InsertCallback: Skyflow.Callback { + public func onSuccess(_ responseBody: Any) { + print(responseBody) + } + public func onFailure(_ error: Any) { + print(error) + } +} + + +// Initialize custom Skyflow.Callback. +let insertCallback = InsertCallback() + +// Call collect method on CollectContainer. +container?.collect(callback: insertCallback, options: collectOptions) +``` -### Validations + +#### Skyflow returns tokens for the record you just updated: +```json +{ + "records": [ + { + "table": "persons", + "fields": { + "gender": "12f670af-6c7d-4837-83fb-30365fbc0b1e", + "skyflow_id": "77dc3caf-c452-49e1-8625-07219d7567bf" + } + }, + { + "table": "cards", + "fields": { + "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882", + "cardNumber": "f3907186-e7e2-466f-91e5-48e12c2bcbc1", + "first_name": "131e70dc-6f76-4319-bdd3-96281e051051" + } + } + ] +} +``` + +## Validations Skyflow-iOS provides two types of validations on Collect Elements @@ -625,9 +816,7 @@ stackView.addArrangedSubview(password!) stackView.addArrangedSubview(confirmPassword!) ``` -### Event Listener on Collect Elements - - +## Event Listener on Collect Elements Helps to communicate with skyflow elements by listening to an event ```swift @@ -738,7 +927,7 @@ cardHolderName.on(eventName: Skyflow.EventName.CHANGE) { state in "value": "" ] ``` -### UI Error for Collect Elements +## UI Error for Collect Elements Helps to display custom error messages on the Skyflow Elements through the methods `setError` and `resetError` on the elements. @@ -777,7 +966,7 @@ cardNumber.setError("custom error") cardNumber.resetError() ``` -### Set and Clear value for Collect Elements (DEV ENV ONLY) +## Set and Clear value for Collect Elements (DEV ENV ONLY) `setValue(value: String)` method is used to set the value of the element. This method will override any previous value present in the element. @@ -817,10 +1006,13 @@ cardNumber.clearValue() ``` # Securely collecting data client-side using Composable Elements +- [Using Skyflow Composable Elements to collect data](#using-skyflow-composable-elements-to-collect-data) +- [Using Skyflow Composable Elements to update data](#using-skyflow-composable-elements-to-update-data) +## Using Skyflow Composable Elements to collect data Composable Elements combine multiple Skyflow Elements in a single row. The following steps create a composable element and securely collect data through it. -## Step 1: Create a composable container +### Step 1: Create a composable container First create a **container** for the form elements using the ```skyflowClient.container(type: Skyflow.ContainerType)``` method as show below @@ -990,7 +1182,7 @@ let collectElementOptions = Skyflow.CollectElementOptions( let element = container?.create(input: composableElementInput, options: collectElementOptions) ``` -## Step 3: Mount Elements to the Screen +### Step 3: Mount Elements to the Screen To specify where the Elements will be rendered on the screen, create a parent UIView (like UIStackView, etc) and you can add composable elements view using `container?.getComposableView()`, it as a subview programmatically. @@ -1014,7 +1206,7 @@ func clearFieldsOnSubmit(_ elements: [TextField]) { } } ``` -## Step 4: Collect data from elements +### Step 4: Collect data from elements When you submit the form, call the `collect(options: Skyflow.CollectOptions? = nil, callback: Skyflow.Callback)` method on the container object. The options parameter takes a `Skyflow.CollectOptions` object as shown below: @@ -1138,7 +1330,6 @@ let insertCallback = InsertCallback() // Call collect method on CollectContainer. container?.collect(callback: insertCallback, options: collectOptions) ``` - ### Sample Response: ``` @@ -1395,6 +1586,258 @@ composableContainer?.on(eventName: .SUBMIT){ ``` +## Using Skyflow Composable Elements to update data +Composable Elements combine multiple Skyflow Elements in a single row. The following steps create a composable element and securely update data through it. + +### Step 1: Create a composable container +First create a **container** for the form elements using the ```skyflowClient.container(type: Skyflow.ContainerType)``` method as show below + +```swift +var containerOptions = ContainerOptions( + layout: [1,1,2], // required + styles: Skyflow.Styles, // optional + errorTextStyles: Skyflow.Styles //optional + ) +let container = skyflowClient.container(type: Skyflow.ContainerType.COMPOSABLE, options: ContainerOptions) +``` + +### Step 2: Create Composable Elements +Composable Elements use the following schema: + +```swift +let composableElementInput = Skyflow.CollectElementInput( + table: String, // optional, the table this data belongs to + column: String, // optional, the column into which this data should be inserted + inputStyles: Skyflow.Styles, // optional styles that should be applied to the form element + labelStyles: Skyflow.Styles, // optional styles that will be applied to the label of the collect element + errorTextStyles: Skyflow.Styles, // optional styles that will be applied to the errorText of the collect element + label: String, // optional label for the form element + placeholder: String, // optional placeholder for the form element + altText: String, // (DEPRECATED) optional that acts as an initial value for the collect element + validations: ValidationSet, // optional set of validations for the input element + type: Skyflow.ElementType, // Skyflow.ElementType enum + skyflowID: String, // The skyflow_id of the record to be updated. +) +``` +The `table` and `column` fields indicate which table and column in the vault the Element correspond to. +**Note**: +- Use dot delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`) + +Along with `CollectElementInput`, you can define other options in the `CollectElementOptions` object which is described below. + +```swift +Skyflow.CollectElementOptions( + required: Boolean, // Indicates whether the field is marked as required. Defaults to 'false' + enableCardIcon: Boolean, // Indicates whether card icon should be enabled (only for CARD_NUMBER inputs) + format: String, // Format for the element + translation: [Character: String] // Indicates the allowed data type value for format. +) +``` + + +Once the `Skyflow.CollectElementInput` and `Skyflow.CollectElementOptions` objects are defined, add to the container using the ```create(input: CollectElementInput, options: CollectElementOptions)``` method as shown below. The `input` param takes a `Skyflow.CollectElementInput` object as defined above and the `options` parameter takes an `Skyflow.CollectElementOptions` object as described below: + + ```swift +let element = container?.create(input: composableElementInput, options: collectElementOptions) +``` +### Step 3: Mount Elements to the Screen + +To specify where the Elements will be rendered on the screen, create a parent UIView (like UIStackView, etc) and you can add composable elements view using `container?.getComposableView()`, it as a subview programmatically. + +```swift +let stackView = UIStackView() +do { + let composableView = try container?.getComposableView() + stackView.addArrangedSubview(composableView) +} catch { + print(error) +} +``` + +The Skyflow Element is an implementation of the UIView so it can be used/mounted similarly. Alternatively, you can use the `unmount` method to reset any collect element to it's initial state + +``` swift +func clearFieldsOnSubmit(_ elements: [TextField]) { + // resets all elements in the array + for element in elements { + element.unmount() + } +} +``` +### Step 4: Update data from Elements +When you submit the form, call the `collect(options: Skyflow.CollectOptions? = nil, callback: Skyflow.Callback)` method on the container object. +The options parameter takes a `Skyflow.CollectOptions` object as shown below: + +- `tokens`: Whether or not tokens for the collected data are returned. Defaults to 'true' +- `additionalFields`: Non-PCI elements data to insert into the vault, specified in the records object format. +- `upsert`: To support upsert operations, the table containing the data and a column marked as unique in that table. + +```swift +// Non-PCI records +let nonPCIRecords = ["table": "persons", "fields": [["gender": "MALE"]]] +// Upsert +let upsertOptions = [["table": "cards", "column": "cardNumber"]] as [[String : Any]] +// Send the non-PCI records as additionalFields of InsertOptions (optional) and apply upsert using `upsert` field of InsertOptions (optional) + +let options = Skyflow.CollectOptions(tokens: true, additionalFields: nonPCIRecords, upsert: upsertOptions) + +//Custom callback - implementation of Skyflow.callback +let insertCallback = InsertCallback() +container?.collect(callback: insertCallback, options: options) +``` +End to end example of collecting data with Composable Elements + +```swift + +//Initialize skyflow configuration. +let config = Skyflow.Configuration(vaultID: VAULT_ID, vaultURL: VAULT_URL, tokenProvider: demoTokenProvider) + +//Initialize skyflow client. +let skyflowClient = Skyflow.initialize(config) + +let containerOptions = ContainerOptions(layout: [1,2], styles: Styles(base: Style(borderColor: UIColor.gray)), errorTextStyles: Styles(base: Style(textColor: UIColor.red))) +//Create a Composable Container. +let container = self.skyflow?.container(type: Skyflow.ContainerType.COMPOSABLE, options: containerOptions) + +//Create Skyflow.Styles with individual Skyflow.Style variants. +let baseStyle = Skyflow.Style(borderColor: UIColor.blue) +let baseTextStyle = Skyflow.Style(textColor: UIColor.black) +let completeStyle = Skyflow.Style(borderColor: UIColor.green) +let focusTextStyle = Skyflow.Style(textColor: UIColor.red) +let inputStyles = Skyflow.Styles(base: baseStyle, complete: completeStyle) +let labelStyles = Skyflow.Styles(base: baseTextStyle, focus: focusTextStyle) +let errorTextStyles = Skyflow.Styles(base: baseTextStyle) + +// Create Composable Elements. + +let cardHolderNameElementInput = Skyflow.CollectElementInput( + table: "cards", + column: "first_name", + inputStyles: inputStyles, + labelStyles: labelStyles, + errorTextStyles: errorTextStyles, + label: "first name", + placeholder: "first name", + type: Skyflow.ElementType.CARDHOLDER_NAME, + skyflowID: "431eaa6c-5c15-4513-aa15-29f50babe882" +) +// Create an option to require the element. +let requiredOption = Skyflow.CollectElementOptions(required: true) + +// Create a Composable Element from the Composable Container. +let cardHolderNameElement = container?.create(input: cardHolderNameElementInput, options: requiredOption) + + +let cardNumberElementInput = Skyflow.CollectElementInput( + table: "cards", + column: "cardNumber", + inputStyles: inputStyles, + labelStyles: labelStyles, + errorTextStyles: errorTextStyles, + label: "card number", + placeholder: "card number", + type: Skyflow.ElementType.CARD_NUMBER, + skyflowID: "431eaa6c-5c15-4513-aa15-29f50babe882" +) + +let cardNumberElement = container?.create(input: cardNumberElementInput, options: requiredOption) + +let cvvElementInput = Skyflow.CollectElementInput( + table: "cards", + column: "cvv", + inputStyles: inputStyles, + labelStyles: labelStyles, + errorTextStyles: errorTextStyles, + label: "cvv", + placeholder: "cvv", + type: Skyflow.ElementType.CVV, + skyflowID: "431eaa6c-5c15-4513-aa15-29f50babe882" +) + +let cvvElement = container?.create(input: cvvElementInput, options: requiredOption) + +// Can interact with this object as a normal UIView Object and add to View +let stackView = UIStackView() +do { + let composableView = try container?.getComposableView() + stackView.addArrangedSubview(composableView) +} catch { + print(error) +} + +// Non-PCI records +let nonPCIRecords = [["table": "persons", "fields": ["gender": "MALE"],"skyflowID": "77dc3caf-c452-49e1-8625-07219d7567bf"]] + + //Upsert options + let upsertOptions = [["table": "cards", "column": "cardNumber"]] as [[String : Any]] + +// Send the Non-PCI records as additionalFields of CollectOptions (optional) and apply upsert using optional field `upsert` of CollectOptions. +let collectOptions = Skyflow.CollectOptions(tokens: true, additionalFields: nonPCIRecords, upsert: upsertOptions) + +//Implement a custom Skyflow.Callback to call on Insertion success/failure. +public class InsertCallback: Skyflow.Callback { + public func onSuccess(_ responseBody: Any) { + print(responseBody) + } + public func onFailure(_ error: Any) { + print(error) + } +} + +// Initialize custom Skyflow.Callback. +let insertCallback = InsertCallback() + +// Call collect method on CollectContainer. +container?.collect(callback: insertCallback, options: collectOptions) +``` +### Sample Success Response: +```json +{ + "records": [ + { + "table": "persons", + "fields": { + "gender": "12f670af-6c7d-4837-83fb-30365fbc0b1e", + "skyflow_id": "77dc3caf-c452-49e1-8625-07219d7567bf" + } + }, + { + "table": "cards", + "fields": { + "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882", + "cardNumber": "f3907186-e7e2-466f-91e5-48e12c2bcbc1", + "first_name": "131e70dc-6f76-4319-bdd3-96281e051051", + "cvv": "098834fe-de99-4fc8-abdf-88c18a28a2cf" + } + } + ] +} +``` +### Sample Partial Error Response: +```json +{ + "records": [ + { + "table": "cards", + "fields": { + "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882", + "cardNumber": "f3907186-e7e2-466f-91e5-48e12c2bcbc1", + "first_name": "131e70dc-6f76-4319-bdd3-96281e051051", + "cvv": "098834fe-de99-4fc8-abdf-88c18a28a2cf" + } + } + ], + "errors": [ + { + "error": { + "code": 400, + "message": "Update failed. skyflow_ids [77dc3caf-c452-49e1-8625-07219d7567bf] are invalid. Specify valid Skyflow IDs. - request-id: cb397-8521-42c2-870c-92dbeec" + } + } + ] +} +``` + # Securely revealing data client-side - [**Retrieving data from the vault**](#retrieving-data-from-the-vault) - [**Using Skyflow Elements to reveal data**](#using-skyflow-elements-to-reveal-data) diff --git a/Samples/UpdateDataUsingElements/Podfile b/Samples/UpdateDataUsingElements/Podfile new file mode 100644 index 00000000..2f3a6cd7 --- /dev/null +++ b/Samples/UpdateDataUsingElements/Podfile @@ -0,0 +1,29 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'UpdateDataUsingElements' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for UpdateDataUsingElements + pod 'AEXML', '4.6.1' +# pod 'Skyflow', '1.24.2' + pod 'Skyflow', :git => 'https://github.com/skyflowapi/skyflow-iOS.git', :branch => 'release/26.3.1' + + target 'UpdateDataUsingElementsTests' do + inherit! :search_paths + # Pods for testing + pod 'AEXML', '4.6.1' +# pod 'Skyflow', '1.24.2' + pod 'Skyflow', :git => 'https://github.com/skyflowapi/skyflow-iOS.git', :branch => 'release/26.3.1' + end + + target 'UpdateDataUsingElementsUITests' do + # Pods for testing + pod 'AEXML', '4.6.1' +# pod 'Skyflow', '1.24.2' + pod 'Skyflow', :git => 'https://github.com/skyflowapi/skyflow-iOS.git', :branch => 'release/26.3.1' + + end + +end diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements.xcodeproj/project.pbxproj b/Samples/UpdateDataUsingElements/UpdateDataUsingElements.xcodeproj/project.pbxproj new file mode 100644 index 00000000..ae700fd2 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements.xcodeproj/project.pbxproj @@ -0,0 +1,756 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + 84209722024122879D341F43 /* Pods_UpdateDataUsingElementsTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BB1BBDB3F2018A417C4B8F5 /* Pods_UpdateDataUsingElementsTests.framework */; }; + A9BAC9FE1923AA2AF6EBDD4A /* Pods_UpdateDataUsingElements.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9A9A41A0A4EEE3FD38922C5 /* Pods_UpdateDataUsingElements.framework */; }; + F9F0ED650060535674C02713 /* Pods_UpdateDataUsingElements_UpdateDataUsingElementsUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A128FC9CED2A962A852D5181 /* Pods_UpdateDataUsingElements_UpdateDataUsingElementsUITests.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 8EE9B1D32F5D47F600E676C7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8EE9B1B42F5D47EF00E676C7 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8EE9B1BB2F5D47EF00E676C7; + remoteInfo = UpdateDataUsingElements; + }; + 8EE9B1DD2F5D47F600E676C7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8EE9B1B42F5D47EF00E676C7 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8EE9B1BB2F5D47EF00E676C7; + remoteInfo = UpdateDataUsingElements; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0BB1BBDB3F2018A417C4B8F5 /* Pods_UpdateDataUsingElementsTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_UpdateDataUsingElementsTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 19501CBC771B67CB4A422639 /* Pods-UpdateDataUsingElementsTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UpdateDataUsingElementsTests.release.xcconfig"; path = "Target Support Files/Pods-UpdateDataUsingElementsTests/Pods-UpdateDataUsingElementsTests.release.xcconfig"; sourceTree = ""; }; + 31FA5C255B7E2C37276B38B3 /* Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests.release.xcconfig"; path = "Target Support Files/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests.release.xcconfig"; sourceTree = ""; }; + 55AA84197F63011C6D16CA15 /* Pods-UpdateDataUsingElements.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UpdateDataUsingElements.release.xcconfig"; path = "Target Support Files/Pods-UpdateDataUsingElements/Pods-UpdateDataUsingElements.release.xcconfig"; sourceTree = ""; }; + 8C4FE748FB9BE72A6F211DA7 /* Pods-UpdateDataUsingElementsTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UpdateDataUsingElementsTests.debug.xcconfig"; path = "Target Support Files/Pods-UpdateDataUsingElementsTests/Pods-UpdateDataUsingElementsTests.debug.xcconfig"; sourceTree = ""; }; + 8EE9B1BC2F5D47EF00E676C7 /* UpdateDataUsingElements.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UpdateDataUsingElements.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8EE9B1D22F5D47F600E676C7 /* UpdateDataUsingElementsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UpdateDataUsingElementsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8EE9B1DC2F5D47F600E676C7 /* UpdateDataUsingElementsUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UpdateDataUsingElementsUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + A128FC9CED2A962A852D5181 /* Pods_UpdateDataUsingElements_UpdateDataUsingElementsUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_UpdateDataUsingElements_UpdateDataUsingElementsUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D9E9FF05FEC4438776BD37D1 /* Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests.debug.xcconfig"; path = "Target Support Files/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests.debug.xcconfig"; sourceTree = ""; }; + DDEEAC96F7413BA8DED5CC43 /* Pods-UpdateDataUsingElements.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UpdateDataUsingElements.debug.xcconfig"; path = "Target Support Files/Pods-UpdateDataUsingElements/Pods-UpdateDataUsingElements.debug.xcconfig"; sourceTree = ""; }; + F9A9A41A0A4EEE3FD38922C5 /* Pods_UpdateDataUsingElements.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_UpdateDataUsingElements.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 8EE9B1E42F5D47F600E676C7 /* Exceptions for "UpdateDataUsingElements" folder in "UpdateDataUsingElements" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = 8EE9B1BB2F5D47EF00E676C7 /* UpdateDataUsingElements */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 8EE9B1BE2F5D47EF00E676C7 /* UpdateDataUsingElements */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 8EE9B1E42F5D47F600E676C7 /* Exceptions for "UpdateDataUsingElements" folder in "UpdateDataUsingElements" target */, + ); + path = UpdateDataUsingElements; + sourceTree = ""; + }; + 8EE9B1D52F5D47F600E676C7 /* UpdateDataUsingElementsTests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + ); + path = UpdateDataUsingElementsTests; + sourceTree = ""; + }; + 8EE9B1DF2F5D47F600E676C7 /* UpdateDataUsingElementsUITests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + ); + path = UpdateDataUsingElementsUITests; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8EE9B1B92F5D47EF00E676C7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A9BAC9FE1923AA2AF6EBDD4A /* Pods_UpdateDataUsingElements.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8EE9B1CF2F5D47F600E676C7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 84209722024122879D341F43 /* Pods_UpdateDataUsingElementsTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8EE9B1D92F5D47F600E676C7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F9F0ED650060535674C02713 /* Pods_UpdateDataUsingElements_UpdateDataUsingElementsUITests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 27820800536265CC8997BEDA /* Pods */ = { + isa = PBXGroup; + children = ( + DDEEAC96F7413BA8DED5CC43 /* Pods-UpdateDataUsingElements.debug.xcconfig */, + 55AA84197F63011C6D16CA15 /* Pods-UpdateDataUsingElements.release.xcconfig */, + D9E9FF05FEC4438776BD37D1 /* Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests.debug.xcconfig */, + 31FA5C255B7E2C37276B38B3 /* Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests.release.xcconfig */, + 8C4FE748FB9BE72A6F211DA7 /* Pods-UpdateDataUsingElementsTests.debug.xcconfig */, + 19501CBC771B67CB4A422639 /* Pods-UpdateDataUsingElementsTests.release.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 46291EA2BCEB4448675D0DA8 /* Frameworks */ = { + isa = PBXGroup; + children = ( + F9A9A41A0A4EEE3FD38922C5 /* Pods_UpdateDataUsingElements.framework */, + A128FC9CED2A962A852D5181 /* Pods_UpdateDataUsingElements_UpdateDataUsingElementsUITests.framework */, + 0BB1BBDB3F2018A417C4B8F5 /* Pods_UpdateDataUsingElementsTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 8EE9B1B32F5D47EF00E676C7 = { + isa = PBXGroup; + children = ( + 8EE9B1BE2F5D47EF00E676C7 /* UpdateDataUsingElements */, + 8EE9B1D52F5D47F600E676C7 /* UpdateDataUsingElementsTests */, + 8EE9B1DF2F5D47F600E676C7 /* UpdateDataUsingElementsUITests */, + 8EE9B1BD2F5D47EF00E676C7 /* Products */, + 27820800536265CC8997BEDA /* Pods */, + 46291EA2BCEB4448675D0DA8 /* Frameworks */, + ); + sourceTree = ""; + }; + 8EE9B1BD2F5D47EF00E676C7 /* Products */ = { + isa = PBXGroup; + children = ( + 8EE9B1BC2F5D47EF00E676C7 /* UpdateDataUsingElements.app */, + 8EE9B1D22F5D47F600E676C7 /* UpdateDataUsingElementsTests.xctest */, + 8EE9B1DC2F5D47F600E676C7 /* UpdateDataUsingElementsUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8EE9B1BB2F5D47EF00E676C7 /* UpdateDataUsingElements */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8EE9B1E52F5D47F600E676C7 /* Build configuration list for PBXNativeTarget "UpdateDataUsingElements" */; + buildPhases = ( + 0F8A093288F474159BEDE644 /* [CP] Check Pods Manifest.lock */, + 8EE9B1B82F5D47EF00E676C7 /* Sources */, + 8EE9B1B92F5D47EF00E676C7 /* Frameworks */, + 8EE9B1BA2F5D47EF00E676C7 /* Resources */, + E938BD775733C7F94C478863 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 8EE9B1BE2F5D47EF00E676C7 /* UpdateDataUsingElements */, + ); + name = UpdateDataUsingElements; + productName = UpdateDataUsingElements; + productReference = 8EE9B1BC2F5D47EF00E676C7 /* UpdateDataUsingElements.app */; + productType = "com.apple.product-type.application"; + }; + 8EE9B1D12F5D47F600E676C7 /* UpdateDataUsingElementsTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8EE9B1EA2F5D47F600E676C7 /* Build configuration list for PBXNativeTarget "UpdateDataUsingElementsTests" */; + buildPhases = ( + 8B6ABD965E2972F8AC0F597B /* [CP] Check Pods Manifest.lock */, + 8EE9B1CE2F5D47F600E676C7 /* Sources */, + 8EE9B1CF2F5D47F600E676C7 /* Frameworks */, + 8EE9B1D02F5D47F600E676C7 /* Resources */, + 87992577B2A3D0F9B4A74C66 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 8EE9B1D42F5D47F600E676C7 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 8EE9B1D52F5D47F600E676C7 /* UpdateDataUsingElementsTests */, + ); + name = UpdateDataUsingElementsTests; + productName = UpdateDataUsingElementsTests; + productReference = 8EE9B1D22F5D47F600E676C7 /* UpdateDataUsingElementsTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 8EE9B1DB2F5D47F600E676C7 /* UpdateDataUsingElementsUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8EE9B1ED2F5D47F600E676C7 /* Build configuration list for PBXNativeTarget "UpdateDataUsingElementsUITests" */; + buildPhases = ( + E3F917F11A21B04E3AE532A9 /* [CP] Check Pods Manifest.lock */, + 8EE9B1D82F5D47F600E676C7 /* Sources */, + 8EE9B1D92F5D47F600E676C7 /* Frameworks */, + 8EE9B1DA2F5D47F600E676C7 /* Resources */, + 7ED4115DECEAE1F715BC3D6F /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 8EE9B1DE2F5D47F600E676C7 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 8EE9B1DF2F5D47F600E676C7 /* UpdateDataUsingElementsUITests */, + ); + name = UpdateDataUsingElementsUITests; + productName = UpdateDataUsingElementsUITests; + productReference = 8EE9B1DC2F5D47F600E676C7 /* UpdateDataUsingElementsUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 8EE9B1B42F5D47EF00E676C7 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1640; + LastUpgradeCheck = 1640; + TargetAttributes = { + 8EE9B1BB2F5D47EF00E676C7 = { + CreatedOnToolsVersion = 16.4; + }; + 8EE9B1D12F5D47F600E676C7 = { + CreatedOnToolsVersion = 16.4; + TestTargetID = 8EE9B1BB2F5D47EF00E676C7; + }; + 8EE9B1DB2F5D47F600E676C7 = { + CreatedOnToolsVersion = 16.4; + TestTargetID = 8EE9B1BB2F5D47EF00E676C7; + }; + }; + }; + buildConfigurationList = 8EE9B1B72F5D47EF00E676C7 /* Build configuration list for PBXProject "UpdateDataUsingElements" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 8EE9B1B32F5D47EF00E676C7; + minimizedProjectReferenceProxies = 1; + packageReferences = ( + 8EE9B1F42F5D489500E676C7 /* XCRemoteSwiftPackageReference "skyflow-iOS" */, + ); + preferredProjectObjectVersion = 77; + productRefGroup = 8EE9B1BD2F5D47EF00E676C7 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8EE9B1BB2F5D47EF00E676C7 /* UpdateDataUsingElements */, + 8EE9B1D12F5D47F600E676C7 /* UpdateDataUsingElementsTests */, + 8EE9B1DB2F5D47F600E676C7 /* UpdateDataUsingElementsUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8EE9B1BA2F5D47EF00E676C7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8EE9B1D02F5D47F600E676C7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8EE9B1DA2F5D47F600E676C7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0F8A093288F474159BEDE644 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-UpdateDataUsingElements-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 7ED4115DECEAE1F715BC3D6F /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 87992577B2A3D0F9B4A74C66 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-UpdateDataUsingElementsTests/Pods-UpdateDataUsingElementsTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-UpdateDataUsingElementsTests/Pods-UpdateDataUsingElementsTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-UpdateDataUsingElementsTests/Pods-UpdateDataUsingElementsTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 8B6ABD965E2972F8AC0F597B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-UpdateDataUsingElementsTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E3F917F11A21B04E3AE532A9 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E938BD775733C7F94C478863 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-UpdateDataUsingElements/Pods-UpdateDataUsingElements-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-UpdateDataUsingElements/Pods-UpdateDataUsingElements-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-UpdateDataUsingElements/Pods-UpdateDataUsingElements-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8EE9B1B82F5D47EF00E676C7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8EE9B1CE2F5D47F600E676C7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8EE9B1D82F5D47F600E676C7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 8EE9B1D42F5D47F600E676C7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8EE9B1BB2F5D47EF00E676C7 /* UpdateDataUsingElements */; + targetProxy = 8EE9B1D32F5D47F600E676C7 /* PBXContainerItemProxy */; + }; + 8EE9B1DE2F5D47F600E676C7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8EE9B1BB2F5D47EF00E676C7 /* UpdateDataUsingElements */; + targetProxy = 8EE9B1DD2F5D47F600E676C7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 8EE9B1E62F5D47F600E676C7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DDEEAC96F7413BA8DED5CC43 /* Pods-UpdateDataUsingElements.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = UpdateDataUsingElements/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = Skyflow.UpdateDataUsingElements; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 8EE9B1E72F5D47F600E676C7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 55AA84197F63011C6D16CA15 /* Pods-UpdateDataUsingElements.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = UpdateDataUsingElements/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = Skyflow.UpdateDataUsingElements; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 8EE9B1E82F5D47F600E676C7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 8EE9B1E92F5D47F600E676C7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 8EE9B1EB2F5D47F600E676C7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8C4FE748FB9BE72A6F211DA7 /* Pods-UpdateDataUsingElementsTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = Skyflow.UpdateDataUsingElementsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UpdateDataUsingElements.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/UpdateDataUsingElements"; + }; + name = Debug; + }; + 8EE9B1EC2F5D47F600E676C7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 19501CBC771B67CB4A422639 /* Pods-UpdateDataUsingElementsTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = Skyflow.UpdateDataUsingElementsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UpdateDataUsingElements.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/UpdateDataUsingElements"; + }; + name = Release; + }; + 8EE9B1EE2F5D47F600E676C7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D9E9FF05FEC4438776BD37D1 /* Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests.debug.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = Skyflow.UpdateDataUsingElementsUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = UpdateDataUsingElements; + }; + name = Debug; + }; + 8EE9B1EF2F5D47F600E676C7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 31FA5C255B7E2C37276B38B3 /* Pods-UpdateDataUsingElements-UpdateDataUsingElementsUITests.release.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = Skyflow.UpdateDataUsingElementsUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = UpdateDataUsingElements; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 8EE9B1B72F5D47EF00E676C7 /* Build configuration list for PBXProject "UpdateDataUsingElements" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8EE9B1E82F5D47F600E676C7 /* Debug */, + 8EE9B1E92F5D47F600E676C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8EE9B1E52F5D47F600E676C7 /* Build configuration list for PBXNativeTarget "UpdateDataUsingElements" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8EE9B1E62F5D47F600E676C7 /* Debug */, + 8EE9B1E72F5D47F600E676C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8EE9B1EA2F5D47F600E676C7 /* Build configuration list for PBXNativeTarget "UpdateDataUsingElementsTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8EE9B1EB2F5D47F600E676C7 /* Debug */, + 8EE9B1EC2F5D47F600E676C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8EE9B1ED2F5D47F600E676C7 /* Build configuration list for PBXNativeTarget "UpdateDataUsingElementsUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8EE9B1EE2F5D47F600E676C7 /* Debug */, + 8EE9B1EF2F5D47F600E676C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 8EE9B1F42F5D489500E676C7 /* XCRemoteSwiftPackageReference "skyflow-iOS" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/skyflowapi/skyflow-iOS.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.24.2; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + }; + rootObject = 8EE9B1B42F5D47EF00E676C7 /* Project object */; +} diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements.xcworkspace/contents.xcworkspacedata b/Samples/UpdateDataUsingElements/UpdateDataUsingElements.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..28e92450 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/AppDelegate.swift b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/AppDelegate.swift new file mode 100644 index 00000000..aa40b1e6 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// UpdateDataUsingElements +// +// Created by Bharti Sagar on 08/03/26. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/AccentColor.colorset/Contents.json b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000..eb878970 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/AppIcon.appiconset/Contents.json b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..23058801 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/Contents.json b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Base.lproj/LaunchScreen.storyboard b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..865e9329 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Base.lproj/Main.storyboard b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Base.lproj/Main.storyboard new file mode 100644 index 00000000..25a76385 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ExampleAPICallback.swift b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ExampleAPICallback.swift new file mode 100644 index 00000000..b08d2305 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ExampleAPICallback.swift @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 Skyflow + */ + +import Foundation +import Skyflow + +public class ExampleAPICallback: Skyflow.Callback { + private var updateSuccess: ((SuccessResponse) -> Void)? + private var updateFailure: ((Any) -> Void)? + private var decoder: JSONDecoder? + + internal init(updateSuccess: @escaping (Any) -> Void, updateFailure: @escaping (Any) -> Void) { + self.updateSuccess = updateSuccess + self.updateFailure = updateFailure + self.decoder = JSONDecoder() + } + + internal init() { + } + + public func onSuccess(_ responseBody: Any) { + if updateSuccess == nil { + print("success:", responseBody) + return + } + do { + let dataString = String(data: try! JSONSerialization.data(withJSONObject: responseBody), encoding: .utf8) + let responseData = Data(dataString!.utf8) + let jsonResponse = try decoder!.decode(SuccessResponse.self, from: responseData) + + updateSuccess!(jsonResponse) + + print("success:", jsonResponse) + } catch { + print("error deserializing", error) + } + } + + public func onFailure(_ error: Any) { + print(error) + if updateFailure != nil { + print("failure:", error) + return + } + print("onfailure", error) + } +} diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ExampleTokenProvider.swift b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ExampleTokenProvider.swift new file mode 100644 index 00000000..75a0efee --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ExampleTokenProvider.swift @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Skyflow + */ + +import Foundation +import Skyflow + +public class ExampleTokenProvider: TokenProvider { + public func getBearerToken(_ apiCallback: Skyflow.Callback) { + if let url = URL(string: "") { + let session = URLSession(configuration: .default) + let task = session.dataTask(with: url) { data, _, error in + if error != nil { + print(error!) + return + } + if let safeData = data { + do { + let x = try JSONSerialization.jsonObject(with: safeData, options: []) as? [String: String] + if let accessToken = x?["accessToken"] { + apiCallback.onSuccess(accessToken) + } + } catch { + print("access token wrong format") + } + } + } + task.resume() + } + } +} diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Info.plist b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Info.plist new file mode 100644 index 00000000..dd3c9afd --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/Info.plist @@ -0,0 +1,25 @@ + + + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ResponseStructs.swift b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ResponseStructs.swift new file mode 100644 index 00000000..4b948ce6 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ResponseStructs.swift @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 Skyflow + */ + +import Foundation + +struct SuccessResponse: Codable { + let records: [Records] +} + +struct Records: Codable { + let fields: Fields? + let table: String + let skyflow_id: String? +} + +struct Fields: Codable { + let cardholder_name: String? + let card_number: String? + let expiry_month: String? + let expiry_year: String? + let cvv: String? + let skyflow_id: String? +} diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/SceneDelegate.swift b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/SceneDelegate.swift new file mode 100644 index 00000000..6f4093b7 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/SceneDelegate.swift @@ -0,0 +1,52 @@ +// +// SceneDelegate.swift +// UpdateDataUsingElements +// +// Created by Bharti Sagar on 08/03/26. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ViewController.swift b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ViewController.swift new file mode 100644 index 00000000..6639ec61 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElements/ViewController.swift @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2022 Skyflow + */ + +import UIKit +import Skyflow + +class ViewController: UIViewController { + var retryCount = 0 + private var skyflow: Skyflow.Client? + private var container: Skyflow.Container? + private var b: UIButton? + + private var stackView: UIStackView! + + override func loadView() { + let view = UIView() + view.backgroundColor = .white + view.translatesAutoresizingMaskIntoConstraints = false + self.view = view + } + + override func viewDidLoad() { + super.viewDidLoad() + + let tokenProvider = ExampleTokenProvider() + + let config = Skyflow.Configuration( + vaultID: "", + vaultURL: "", + tokenProvider: tokenProvider, + options: Skyflow.Options( + logLevel: Skyflow.LogLevel.DEBUG + ) + ) + + self.skyflow = Skyflow.initialize(config) + + if self.skyflow != nil { + let container = self.skyflow?.container(type: Skyflow.ContainerType.COMPOSABLE, options: ContainerOptions(layout: [1,2,2], styles: Styles(base: Style(borderColor: UIColor.gray) ), errorTextStyles: Styles(base: Style(textColor: UIColor.red) ))) + self.container = container + self.stackView = UIStackView() + + let baseStyle = Skyflow.Style( + cornerRadius: 2, + padding: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10), + borderWidth: 1, + textAlignment: .left, + textColor: .blue + ) + + let focusStyle = Skyflow.Style(borderColor: .blue) + + let completedStyle = Skyflow.Style(textColor: UIColor.green) + + let invalidStyle = Skyflow.Style(textColor: UIColor.red) + + let styles = Skyflow.Styles( + base: baseStyle, + complete: completedStyle, + focus: focusStyle, + invalid: invalidStyle + ) + + let collectCardNumberInput = Skyflow.CollectElementInput( + table: "credit_cards", + column: "card_number", + inputStyles: styles, + label: "Card Number", + placeholder: "4111-1111-1111-1111", + type: Skyflow.ElementType.CARD_NUMBER, + skyflowID: "" // replace it with actual skyflowID if you want to test update with elements functionality, otherwise you can remove skyflowID field from input + + ) + let collectNameInput = Skyflow.CollectElementInput( + table: "credit_cards", + column: "cardholder_name", + inputStyles: styles, + label: "Card Holder Name", + placeholder: "John Doe", + type: Skyflow.ElementType.CARDHOLDER_NAME, + skyflowID: "" // replace it with actual skyflowID if you want to test update with elements functionality, otherwise you can remove skyflowID field from input + ) + let collectCVVInput = Skyflow.CollectElementInput( + table: "credit_cards", + column: "cvv", + inputStyles: styles, + label: "CVV", + placeholder: "***", + type: .CVV, + skyflowID: "" // replace it with actual skyflowID if you want to test update with elements functionality, otherwise you can remove skyflowID field from input + ) + let collectExpMonthInput = Skyflow.CollectElementInput( + table: "credit_cards", + column: "expiry_month", + inputStyles: styles, + label: "Expiration Month", + placeholder: "MM", + type: .EXPIRATION_MONTH, + skyflowID: "" // replace it with actual skyflowID if you want to test update with elements functionality, otherwise you can remove skyflowID field from input + + ) + let collectExpYearInput = Skyflow.CollectElementInput( + table: "credit_cards", + column: "expiry_year", + inputStyles: styles, + label: "Expiration Year", + placeholder: "YYYY", + type: .EXPIRATION_YEAR, + skyflowID: "" // replace it with actual skyflowID if you want to test update with elements functionality, otherwise you can remove skyflowID field from input + + ) + let requiredOption = Skyflow.CollectElementOptions(required: true) + let collectCardNumber = container?.create(input: collectCardNumberInput, options: requiredOption) + let collectName = container?.create(input: collectNameInput, options: requiredOption) + let collectCVV = container?.create(input: collectCVVInput, options: requiredOption) + let collectExpMonth = container?.create(input: collectExpMonthInput, options: requiredOption) + let collectExpYear = container?.create(input: collectExpYearInput, options: requiredOption) + let collectButton = UIButton(frame: CGRect(x: 100, y: 400, width: 100, height: 40)) + collectButton.backgroundColor = .blue + collectButton.setTitle("Submit", for: .normal) + collectButton.addTarget(self, action: #selector(submitForm), for: .touchUpInside) + + do { + let composableView = try container?.getComposableView() + stackView.addArrangedSubview(composableView) + } catch { + print(error) + } + + stackView.addArrangedSubview(collectButton) + stackView.axis = .vertical + stackView.distribution = .fill + stackView.spacing = 10 + stackView.alignment = .fill + stackView.translatesAutoresizingMaskIntoConstraints = false + let scrollView = UIScrollView(frame: .zero) + scrollView.isScrollEnabled = true + scrollView.backgroundColor = .white + scrollView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(scrollView) + scrollView.topAnchor.constraint( + equalTo: view.safeAreaLayoutGuide.topAnchor, + constant: 20 + ).isActive = true + scrollView.leftAnchor.constraint( + equalTo: view.safeAreaLayoutGuide.leftAnchor, + constant: 10 + ).isActive = true + scrollView.rightAnchor.constraint( + equalTo: view.safeAreaLayoutGuide.rightAnchor, + constant: -10 + ).isActive = true + scrollView.bottomAnchor.constraint( + equalTo: view.safeAreaLayoutGuide.bottomAnchor + ).isActive = true + scrollView.addSubview(stackView) + stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -10).isActive = true + stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true + stackView.leftAnchor.constraint(equalTo: scrollView.leftAnchor).isActive = true + stackView.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: -10).isActive = true + stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true + } + } + + @objc func submitForm() { + let exampleAPICallback = ExampleAPICallback(updateSuccess: updateSuccess, updateFailure: updateFailure) + container!.collect(callback: exampleAPICallback, options: Skyflow.CollectOptions(tokens: true)) + } + internal func updateSuccess(_ response: SuccessResponse) { + print(response) + retryCount = 0 + print("Successfully got response:", response) + } + internal func updateFailure(error: Any) { + if((error as AnyObject).contains("Invalid Bearer token") && retryCount <= 2){ // To do, it will be replaced with error code in the future + retryCount += 1 + submitForm() + } + print("Failed Operation", error) + } + +} diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElementsTests/UpdateDataUsingElementsTests.swift b/Samples/UpdateDataUsingElements/UpdateDataUsingElementsTests/UpdateDataUsingElementsTests.swift new file mode 100644 index 00000000..eada6780 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElementsTests/UpdateDataUsingElementsTests.swift @@ -0,0 +1,36 @@ +// +// UpdateDataUsingElementsTests.swift +// UpdateDataUsingElementsTests +// +// Created by Bharti Sagar on 08/03/26. +// + +import XCTest +@testable import UpdateDataUsingElements + +final class UpdateDataUsingElementsTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElementsUITests/UpdateDataUsingElementsUITests.swift b/Samples/UpdateDataUsingElements/UpdateDataUsingElementsUITests/UpdateDataUsingElementsUITests.swift new file mode 100644 index 00000000..a921baab --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElementsUITests/UpdateDataUsingElementsUITests.swift @@ -0,0 +1,41 @@ +// +// UpdateDataUsingElementsUITests.swift +// UpdateDataUsingElementsUITests +// +// Created by Bharti Sagar on 08/03/26. +// + +import XCTest + +final class UpdateDataUsingElementsUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // 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. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + @MainActor + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + @MainActor + func testLaunchPerformance() throws { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } +} diff --git a/Samples/UpdateDataUsingElements/UpdateDataUsingElementsUITests/UpdateDataUsingElementsUITestsLaunchTests.swift b/Samples/UpdateDataUsingElements/UpdateDataUsingElementsUITests/UpdateDataUsingElementsUITestsLaunchTests.swift new file mode 100644 index 00000000..81b9cb73 --- /dev/null +++ b/Samples/UpdateDataUsingElements/UpdateDataUsingElementsUITests/UpdateDataUsingElementsUITestsLaunchTests.swift @@ -0,0 +1,33 @@ +// +// UpdateDataUsingElementsUITestsLaunchTests.swift +// UpdateDataUsingElementsUITests +// +// Created by Bharti Sagar on 08/03/26. +// + +import XCTest + +final class UpdateDataUsingElementsUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + @MainActor + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} From c265835b526e04850366931628969256448098eb Mon Sep 17 00:00:00 2001 From: skyflow-bharti Date: Mon, 9 Mar 2026 18:08:54 +0530 Subject: [PATCH 2/2] SK-2592 update sdk version in sample pod file --- Samples/UpdateDataUsingElements/Podfile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Samples/UpdateDataUsingElements/Podfile b/Samples/UpdateDataUsingElements/Podfile index 2f3a6cd7..288940eb 100644 --- a/Samples/UpdateDataUsingElements/Podfile +++ b/Samples/UpdateDataUsingElements/Podfile @@ -7,22 +7,19 @@ target 'UpdateDataUsingElements' do # Pods for UpdateDataUsingElements pod 'AEXML', '4.6.1' -# pod 'Skyflow', '1.24.2' - pod 'Skyflow', :git => 'https://github.com/skyflowapi/skyflow-iOS.git', :branch => 'release/26.3.1' + pod 'Skyflow', '1.25.0' target 'UpdateDataUsingElementsTests' do inherit! :search_paths # Pods for testing pod 'AEXML', '4.6.1' -# pod 'Skyflow', '1.24.2' - pod 'Skyflow', :git => 'https://github.com/skyflowapi/skyflow-iOS.git', :branch => 'release/26.3.1' + pod 'Skyflow', '1.25.0' end target 'UpdateDataUsingElementsUITests' do # Pods for testing pod 'AEXML', '4.6.1' -# pod 'Skyflow', '1.24.2' - pod 'Skyflow', :git => 'https://github.com/skyflowapi/skyflow-iOS.git', :branch => 'release/26.3.1' + pod 'Skyflow', '1.25.0' end