Sample Code Snippets - iOS SDK | Zoho Creator Help

Sample code snippets

Below are code snippets that demonstrate how to use the different methods of Zoho Creator's SDK for iOS:

To construct the FieldAccessPath

FieldAccessPath allows you to access the required field in the required form. Constructing it differs as follows:

For a regular field :


FieldAccessPath.field(linkName: <FieldLinkName>)


For a subfield (of a composite field); for example, the first_name field in name, or the country field in the address field:


FieldAccessPath.compositeField(linkName: <CompositeFieldLinkName>, subFieldLinkName: <SubFieldLinkName>)


For a normal field inside a subform:

FieldAccessPath.subFormField(linkName: <SubFormLinkName>, entryId: <EntryId>, fieldLinkName: <FieldLinkName>)


For a subfield (of a composite field) inside a subform:


FieldAccessPath.subFormCompositeField(linkName: <CompositeFieldLinkName>, subFormLinkName: <SubFormLinkName>, entryId: <EntryId>, subFieldLinkName: <SubFieldLinkName>)

 

To fetch a form object

To fetch a form object in the way it appears when it's accessed to add a record:


let formInfo = FormInfo(linkName: <FormLinkName>, displayName: <FormDisplayName>)
ZCFormAPIService.fetch(for: formInfo) { (workFlowChangeSetResult) in
    switch workFlowChangeSetResult {
      case .success(let changeSet)
        let form = changeSet.form
      case .failure(_):
        //Failure
      }
  }


To fetch a form object in the way it appears when it's accessed to edit a record:


let formInfo = FormInfo(linkName: <FormLinkName>, displayName: <FormDisplayName>)
ZCFormAPIService.fetch(forRecordID: <RecordId>, reportLinkName: <ReportLinkName>, formInfo: <FormInfo>) { (result) in
      switch workFlowChangeSetResult {
        case .success(let changeSet):
          let form = changeSet.form
        case .failure(_):
          //Failure
      }
  }

 

To fetch the choices from a field

In Zoho Creator, choices are displayed by the following field types: drop downradiomulti selectcheckboxlookup, prefix subfield of the name field, the country subfield of the address field. Refer to this section to construct the required field's AccessPath. To fetch the choices that a field displays when a form is accessed to add a record:


// Check FieldAccessPath construction as reference
let fieldAccessPath = FieldAccess.field(linkName: <ChoiceFieldLinkName>)
ZCFormAPIService.fetchChoices(forSearchString: <SearchString>, of: fieldAccessPath, in: <form>, fromIndex: <FromIndex>) { (result) in
    switch result {
      case .success(let choices):
        //choices
      case .failure(_):
        //failure
      }
  }


To fetch the choices that a field displays when a form is accessed to edit a record:


let fieldAccessPath = FieldAccess.field(linkName: <ChoiceFieldLinkName>)
ZCFormAPIService.fetchChoices(withRecordID: <Record Id>, forReportLinkName: <ReportLinkName>, forSearchString: <Search String>, of: fieldAccessPath, in: <form>, fromIndex: <FromInde>) { (result) in
    switch result {
      case .success(let choices):
        //choices
      case .failure(_):
        //failure
      }
  }

 

To submit a form

To submit a form to add a record:


ZCFormAPIService.submit(form: <Form>) { (result) in
    switch result {
      case .success(let response):
        //Submit response
      case .failure(let error):
        //Error
    }
  }


To submit a form to edit a record:


ZCFormAPIService.updateRecord(withRecordID: <recordLinkID>, inReportLinkName: <ReportLinkName>,form: <Form>) { (result) in
    switch result {
      case .success(let response):
        //Submit response
      case .failure(let error):
        //Error
    }
}

 

To set a field's value

  1. Construct the required field's AccessPath.
  2. Get field and index from the Form:
    
    <form>.getFieldAndIndex(using: <fieldAccessPath>)
    // (field,index)
    
  3. Get the field's current value:
    
    <field>.getValue()
    // InputValues
    
  4. Set the required value for the field:
    • To set value for a single lineemailnumberpercentdecimalcurrencymulti linerich textadd notesdatedate-time, or time field:
      
      InputValues.textFieldValue(fieldValue:<your_input>)
      
    • To set the value for a decision box field:
      
      InputValues.decisionFieldValue(fieldValue: <boolean_value>)
      
    • To set the value for a drop downradiolookup (single-select), users, and integration field:
      
      if case InputValues.singleSelectChoiceFieldValue(var existingValue) = <field>.getValue() {
         existingValue.selectedChoice = { you can select appropriate value from existingValue.choice  }
         let newField = field.setValueFor(value: existingValue) //updated field
      }
      
    • To set the value for a checkboxmulti select, or lookup (multi-select) field:
      
      if case InputValues.multiSelectChoiceFieldValue(var existingValue) = <field>.getValue() {
         existingValue.selectedChoice = { you can select appropriate value from existingValue.choice  }
         let newField = field.setValueFor(value: existingValue) //updated field
      }
      
    • To set the value for a phone field:
      
      let newField = field.setValueFor(value: InputValues.phoneNumberFieldValue(countryCode:<Code>,number: <PhoneNumber>))
      
    • To set the value for a URL field:
      
      let newField = field.setValueFor(value: InputValues.urlFieldValue(url:<url>,title:<title>,linkName:<linkName>))
      
  5. Update the field to the form:
    
    <form>.setField(updatedField,at: index)
    

To upload a file to a media field and submit the form

To upload a file to an imagefile uploadaudiovideo, or signature field and submit the form to add a record:


func submitMediaField(media: Data,filename:String ,fieldLinkName: String){
        let formInfo = FormInfo(linkName: "<formLinkName>", displayName: "<formDisplayName>", appLinkName: "<AppLinkName>", appOwner: "<AppOwner>", openUrlInfo: nil)
    // fetch form
        ZCFormAPIService.fetch(for: formInfo) { result in
            switch result {
            case .failure(let error):
                print(error)
            case .sucess(let workChange):
                var form = workChange.alteredForm
                let fieldAccessPath = FieldAccessPath.field(linkName: fieldLinkName)
        //get field value
                if  let (field,index) = form.getFieldAndIndex(using: fieldAccessPath),
                    case InputValues.mediaFieldValue(var fieldValue) = field.getValue() {
        //upload media
                    ZCFormAPIService.upload(media: media, withFileName: filename, for: fieldAccessPath, form: form) { (mediaResponse) in
                        switch mediaResponse {
                        case .sucess(let mediaResults):
        //set media field value
                            fieldValue.fileName = mediaResults.fileName
                            if let updatedField = field.setValueFor(value: .mediaFieldValue(fieldValue: fieldValue)) {
                                form.setField(updatedField, at: index)
            //submit the form
                                ZCFormAPIService.submit(form: form) { (submitResponse) in
                                    switch submitResponse {
                                    case .sucess(let successResponse):
                                        // Success Response
                                        print("Success")
                                    case .failure(_):
                                        //failure
                                        print("Failure")
                                    }
                                }
                            }
                        case .failure(let error):
                            print(error)
                        }
                    }
                }
            }
        }
    }


To upload a file to an imagefile uploadaudiovideo, or signature field and submit the form to update a record:


func updateMediaField(media: Data,filename:String ,fieldLinkName: String,recordId: String,reportLinkName: String){
        let formInfo = FormInfo(linkName: "<formLinkName>", displayName: "<formDisplayName>", appLinkName: "<AppLinkName>", appOwner: "<AppOwner>", openUrlInfo: nil)
        ZCFormAPIService.fetch(forRecordID: recordId, reportLinkName: reportLinkName, formInfo: formInfo) { result in
            switch result {
            case .failure(let error):
                print(error)
            case .sucess(let workChange):
                var form = workChange.alteredForm
                let fieldAccessPath = FieldAccessPath.field(linkName: fieldLinkName)
                if  let (field,index) = form.getFieldAndIndex(using: fieldAccessPath),
                    case InputValues.mediaFieldValue(var fieldValue) = field.getValue() {
        //upload the media
                    ZCFormAPIService.upload(media: media, withFileName: filename, for: fieldAccessPath, form: form) { (mediaResponse) in
                        switch mediaResponse {
                        case .sucess(let mediaResults):
        // set media field value
                            fieldValue.fileName = mediaResults.fileName
                            if let updatedField = field.setValueFor(value: .mediaFieldValue(fieldValue: fieldValue)) {
                                form.setField(updatedField, at: index)
            // update the record
                                ZCFormAPIService.updateRecord(withRecordID: recordId, inReportLinkName: reportLinkName, form: form) { (submitResponse) in
                                    switch submitResponse {
                                    case .sucess(let successResponse):
                                        // Success Response
                                        print("Success")
                                    case .failure(_):
                                        //failure
                                        print("Failure")
                                    }
                                }
                            }
                        case .failure(let error):
                            print(error)
                        }
                    }
                }
            }
        }
    }

 

To fetch the sections present in a Creator app


let firstApp = self.appList.applications[0] ZCAPIService.fetchSectionList(for: firstApp, completionHandler: { (result) in
    switch result{
    case .failure(let error):
        // handle error
    case .sucess(let sectionList):        
        //handle sectionList
        self.sectionList = sectionList
}
})

 

To fetch a report

let reportInfo = ReportInfo(openUrlInfo: nil, appOwner: "<app-owner>", appLinkName: "<app-link-name>", linkName: "<report-link-name>", type: .report, appDisplayname: nil, displayName: nil, notificationEnabled: false)
        let config = ListReportAPIConfiguration(fromIndex: 1, limit: 50, moreInfo: ReportAPIConfiguration.init())
        ZCReportAPIService.fetchListReport(for: reportInfo, with: config) { (result) in
            switch result{
            case .failure(let error):
                print(error)
            case .sucess(let listReport):
                //handle success
                print(listReport)
            }
        }

To process the records present in a report

ZCReportAPIService.fetchListReport(for: reportInfo, with: configuration) { (result) in
    
    switch result {
    case .success(let listReport):
        
        guard let firstRecord = listReport.records.first //Returns the first record. (You can also point to the desired record)
            else { return }
        
        do {
            let recordValue = try firstRecord.recordValue(for: "<Field Link Name of the desired Field>")
            
            //Returns the display string from the field you specified above
            let displayString = recordValue.value.displayValue(for: recordValue.column)
            
            
            //For further processing the received value
            switch  recordValue.value {
            case .text(let textValue): //For text value fields: single line, multi line, email, number, date, rich text, etc.
                textValue.value //Returns the string
                
            case .file(let fileValue): //For media fields: file upload, image, audio, video, signature
                fileValue.valueUrl //Returns the URL of the file
                fileValue.apiServiceProperties //Returns additional properties invloved with the field
                
            case .name(let nameValue): //For the name field
                nameValue.value //Returns the name field's display value
                nameValue.subValues //Returns subfield values from the name field: prefix, first_name, last_name, suffix
                
            case .address(let addressValue): //For the address field
                addressValue.value //Returns the address field's display vale
                addressValue.subValues //Returns subfield values from the address field: address_line_1, address_line_2, district_city, state_province, postal_Code, country
                addressValue.latitude //Returns the latitude, if available
                addressValue.longitude //Returns the longitude, if available
                
            case .phoneNumber(let phoneNumberValue): //For the phone field
                phoneNumberValue.value //Returns the phone number
                
            case .link(let linkValue): //For the link field
                linkValue.value //Returns the link field's display value
                linkValue.link //Returns the link corresponding to the field
                
            case .linkedRecords(let linkedRecordValues, delimiter: let delimiter): //For the lookup or subform field, where the Link to View property is configured
                let linkedRecord = linkedRecordValues.first //Returns the first record. (You can also point to the desired record)
                linkedRecord?.value //Returns the record's display string
                linkedRecord?.recordID //Returns the record's ID
                
            case .choices(let choiceValues, delimiter: let delimiter): //For the choice fields: radio, drop down, multi select, checkbox
                let choiceValue = choiceValues.first //Returns the first choice. (You can also point to the desired choice)
                choiceValue?.value //Returns the choice's string
                
            case .values(let values): //For the multi-select lookup field's related value
                //Here "values" is an array which can be further processed as given above
                break
            }
            
        } catch let recordValueError {
            print("\(recordValueError) occurred while processing Record Value")
        }
        
    case .failure(let error):
        //Handle errors here
        print("Report Error Occurred: \(error)")
    }
 }

To fetch notification history


func fetchAllNotifications() {
 ZCAPIService.fetchUserInfo {(result) in
  switch (result)
   {
   case .success(let userInfo):
    ZCAPIService.fetchNewNotifications(lastNotificationID: nil, filterUnread: false, filteredApp: nil) { notificationsResult in
      switch(notificationsResult)
       {
       case .success(let notificationList):
        print ("\(notificationList)")
       case .failure(let error):
        print ("\(error)")
       }
    }
   case .failure(let error):
    print ("\(error)")
  }
 }
}

To show record summary when end-user taps on the notification


func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
 if let notificationInfo = response.notification.request.content.userInfo as? [String: Any] {
  if ZCNotificationService.isCreatorServerNotification(notificationInfo: notificationInfo) == true {
   if let zcNotification = ZCNotificationService.zcNotification(notificationInfo)
   {
    let summaryVC = ZCUIService.getNotificationController(for: zcNotification)
    window?.rootViewController?.present(UINavigationController.init(rootViewController: summaryVC), animated: true, completion: nil)
   }
  }
  else
  {
   // Not from Zoho Creator server
  }
  completionHandler()
 }
}

To fetch record's meta data from the notification


 func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
  if let notificationInfo = response.notification.request.content.userInfo as? [String: Any] {
   if ZCNotificationService.isCreatorServerNotification(notificationInfo: notificationInfo) == true {
    if let zcNotification = ZCNotificationService.zcNotification(notificationInfo) {
     ZCAPIService.fetchNewNotificationRedirectionInfo(notificationID: zcNotification.notificationID, category: zcNotification.category) { result in
      switch (result)
       {
       case .success(let notificationRecordInfo):
        print ("\(notificationRecordInfo)")
       case .failure(let error):
        print ("\(error)")
      }
     }
    }
   }
   else
    {
    // Not from Zoho Creator server
    }
   completionHandler()
  }
 }