in iOS/MyStudies/MyStudies/Views/Steps/ActivityStep/ActivityQuestionStep.swift [273:943]
func getQuestionStep() -> ORKQuestionStep? {
if Utilities.isValidValue(someObject: resultType as AnyObject?) {
var questionStepAnswerFormat: ORKAnswerFormat? // Contains the answerFormat for specific question Type
var questionStep: ORKQuestionStep? // Contains the QuestionStep instance
var placeholderText: String? = ""
// Assigning the answerFormat for the questionStep based on questionStep
switch QuestionStepType(rawValue: (resultType as? String)!)! as QuestionStepType {
case .scale:
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionScaleMaxValue] as AnyObject?
)
&& Utilities.isValidValue(
someObject: formatDict?[kStepQuestionScaleMinValue] as AnyObject?
)
&& Utilities.isValidValue(
someObject: formatDict?[kStepQuestionScaleDefaultValue] as AnyObject?
)
&& Utilities.isValidValue(
someObject: formatDict?[kStepQuestionScaleStep] as AnyObject?
)
&& Utilities.isValidValue(
someObject: formatDict?[kStepQuestionScaleVertical] as AnyObject?
)
{
let maxDesc = formatDict?[kStepQuestionScaleMaxDesc] as? String
let minDesc = formatDict?[kStepQuestionScaleMinDesc] as? String
// Checking if difference is divisible
let difference =
(formatDict?[kStepQuestionScaleMaxValue] as? Int)! - (formatDict?[kStepQuestionScaleMinValue] as? Int)!
let divisibleValue = difference % (formatDict?[kStepQuestionScaleStep] as? Int)!
let stepsValue = difference / (formatDict?[kStepQuestionScaleStep] as? Int)!
let defaultPosition = (formatDict?[kStepQuestionScaleDefaultValue] as? Int)!
var defaultValue = defaultPosition * stepsValue
// Setting the default Value if Exist
if defaultValue > (formatDict?[kStepQuestionScaleMaxValue] as? Int)! {
defaultValue = (formatDict?[kStepQuestionScaleMaxValue] as? Int)!
}
if ((formatDict?[kStepQuestionScaleMaxValue] as? Int)! != (formatDict?[kStepQuestionScaleMinValue] as? Int)!)
&& divisibleValue == 0 && (stepsValue >= 1 && stepsValue <= 13)
{
questionStepAnswerFormat = ORKAnswerFormat.scale(
withMaximumValue: (formatDict?[kStepQuestionScaleMaxValue] as? Int)!,
minimumValue: (formatDict?[kStepQuestionScaleMinValue] as? Int)!,
defaultValue: (formatDict?[kStepQuestionScaleDefaultValue] as? Int)!,
step: (formatDict?[kStepQuestionScaleStep] as? Int)!,
vertical: (formatDict?[kStepQuestionScaleVertical] as? Bool)!,
maximumValueDescription: maxDesc,
minimumValueDescription: minDesc
)
// Setting the Max & Min Images if exist
if Utilities.isValidValue(
someObject: (formatDict?[kStepQuestionScaleMaxImage] as? String as AnyObject)
)
&& Utilities.isValidValue(
someObject: (formatDict?[kStepQuestionScaleMinImage] as? String as AnyObject)
)
{
let minImageBase64String = (formatDict![kStepQuestionScaleMinImage] as? String)!
let minNormalImage = imageFromBase64(minImageBase64String)
let maxImageBase64String = (formatDict![kStepQuestionScaleMaxImage] as? String)!
let maxNormalImage = imageFromBase64(maxImageBase64String)
(questionStepAnswerFormat as? ORKScaleAnswerFormat)!.minimumImage = minNormalImage
(questionStepAnswerFormat as? ORKScaleAnswerFormat)!.maximumImage = maxNormalImage
}
} else {
return nil
}
} else {
return nil
}
case .continuousScale:
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionContinuosScaleMaxFractionDigits]
as AnyObject?
)
&& formatDict?[kStepQuestionContinuosScaleVertical] != nil
{
let maxDesc = formatDict?[kStepQuestionContinuosScaleMaxDesc] as? String
let minDesc = formatDict?[kStepQuestionContinuosScaleMinDesc] as? String
var maxValue = 0.0
var minValue = -1.0
var defaultValue = 0.0
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionContinuosScaleMaxValue] as AnyObject?
) {
maxValue = (formatDict?[kStepQuestionContinuosScaleMaxValue] as? Double)!
} else {
if let value = (formatDict?[kStepQuestionContinuosScaleMaxValue] as? Double) {
if value > 0 {
minValue = (formatDict?[kStepQuestionContinuosScaleMaxValue] as? Double)!
}
}
}
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionContinuosScaleMaxValue] as AnyObject?
) {
minValue = (formatDict?[kStepQuestionContinuosScaleMinValue] as? Double)!
} else {
if let value = (formatDict?[kStepQuestionContinuosScaleMinValue] as? Double) {
if value > 0 {
minValue = (formatDict?[kStepQuestionContinuosScaleMinValue] as? Double)!
}
}
}
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionContinuosScaleDefaultValue]
as AnyObject?
) {
defaultValue = (formatDict?[kStepQuestionContinuosScaleDefaultValue] as? Double)!
} else {
if let value = (formatDict?[kStepQuestionContinuosScaleDefaultValue] as? Double) {
if value > 0 {
defaultValue = (formatDict?[kStepQuestionContinuosScaleDefaultValue] as? Double)!
}
}
}
if (formatDict?[kStepQuestionContinuosScaleMinValue] as? Double)!
!= (formatDict?[kStepQuestionContinuosScaleMaxValue] as? Double)!
{
questionStepAnswerFormat = ORKAnswerFormat.continuousScale(
withMaximumValue: maxValue,
minimumValue: minValue,
defaultValue: defaultValue,
maximumFractionDigits: (formatDict?[kStepQuestionContinuosScaleMaxFractionDigits] as? Int)!,
vertical: (formatDict?[kStepQuestionContinuosScaleVertical] as? Bool)!,
maximumValueDescription: maxDesc,
minimumValueDescription: minDesc
)
// setting the min & max images if exists
if Utilities.isValidValue(
someObject: (formatDict?[kStepQuestionContinuosScaleMaxImage] as? String as AnyObject)
)
&& Utilities.isValidValue(
someObject: (formatDict?[kStepQuestionContinuosScaleMinImage] as? String as AnyObject)
)
{
let minImageBase64String = (formatDict![kStepQuestionContinuosScaleMinImage] as? String)!
let minNormalImage = imageFromBase64(minImageBase64String)
let maxImageBase64String = (formatDict![kStepQuestionContinuosScaleMaxImage] as? String)!
let maxNormalImage = imageFromBase64(maxImageBase64String)
(questionStepAnswerFormat as? ORKContinuousScaleAnswerFormat)!
.minimumImage = minNormalImage
(questionStepAnswerFormat as? ORKContinuousScaleAnswerFormat)!
.maximumImage = maxNormalImage
}
} else {
return nil
}
} else {
return nil
}
case .textscale:
if Utilities.isValidObject(
someObject: formatDict?[kStepQuestionTextScaleTextChoices] as AnyObject?
)
&& Utilities.isValidValue(
someObject: formatDict?[kStepQuestionTextScaleDefault] as AnyObject?
)
&& Utilities.isValidValue(
someObject: formatDict?[kStepQuestionTextScaleVertical] as AnyObject?
)
{
let textChoiceArray: [ORKTextChoice]?
let defaultValue = (formatDict?[kStepQuestionTextScaleDefault] as? Int)!
self.textScaleDefaultValue = "\(defaultValue)"
let textChoiceDict =
formatDict?[kStepQuestionTextScaleTextChoices] as? [Any]
?? []
textChoiceArray = self.getTextChoices(dataArray: textChoiceDict).0
questionStepAnswerFormat = ORKAnswerFormat.textScale(
with: textChoiceArray!,
defaultIndex: defaultValue - 1,
vertical: (formatDict?[kStepQuestionTextScaleVertical] as? Bool)!
)
} else {
return nil
}
case .valuePicker:
if Utilities.isValidObject(
someObject: formatDict?[kStepQuestionTextScaleTextChoices] as AnyObject?
) {
let textChoiceArray: [ORKTextChoice]?
let textChoiceDict =
formatDict?[kStepQuestionTextScaleTextChoices] as? [Any]
?? []
textChoiceArray = self.getTextChoices(dataArray: textChoiceDict).0
questionStepAnswerFormat = ORKAnswerFormat.valuePickerAnswerFormat(
with: textChoiceArray!
)
} else {
return nil
}
case .imageChoice:
if Utilities.isValidObject(
someObject: formatDict?[kStepQuestionImageChoices] as AnyObject?
) {
let imageChoiceArray: [ORKImageChoice]?
imageChoiceArray = self.getImageChoices(
dataArray: (formatDict?[kStepQuestionImageChoices] as? NSArray)!
)
if imageChoiceArray == nil {
return nil
}
questionStepAnswerFormat = ORKAnswerFormat.choiceAnswerFormat(
with: imageChoiceArray!
)
} else {
return nil
}
case .textChoice:
if Utilities.isValidObject(
someObject: formatDict?[kStepQuestionTextChoiceTextChoices] as AnyObject?
)
&& Utilities.isValidValue(
someObject: formatDict?[kStepQuestionTextChoiceSelectionStyle] as AnyObject?
)
{
let textChoiceDict =
formatDict?[kStepQuestionTextChoiceTextChoices] as? [Any]
?? []
let choiceResult = ((formatDict?[kStepQuestionTextChoiceSelectionStyle] as? String)!)
== kStepQuestionTextChoiceSelectionStyleSingle ?
self.getTextChoicesSingleSelection(dataArray: textChoiceDict) : self.getTextChoices(dataArray: textChoiceDict)
// let choiceResult = self.getTextChoicesSingleSelection(dataArray: textChoiceDict)
var otherChoice: OtherChoice? = choiceResult.1
otherChoice = (otherChoice == nil) ? OtherChoice() : otherChoice
let textChoiceArray: [ORKTextChoice]? = choiceResult.0
if ((formatDict?[kStepQuestionTextChoiceSelectionStyle] as? String)!)
== kStepQuestionTextChoiceSelectionStyleSingle
{
// single choice
questionStepAnswerFormat = ORKTextChoiceAnswerFormat(
style: ORKChoiceAnswerStyle.singleChoice,
textChoices: textChoiceArray!
)
} else if ((formatDict?[kStepQuestionTextChoiceSelectionStyle] as? String)!)
== kStepQuestionTextChoiceSelectionStyleMultiple
{
// multiple choice
questionStepAnswerFormat = ORKTextChoiceAnswerFormat(
style: ORKChoiceAnswerStyle.multipleChoice,
textChoices: textChoiceArray!
)
} else {
return nil
}
questionStep = QuestionStep(
identifier: key!,
title: "",
question: title!,
answer: questionStepAnswerFormat!,
otherChoice: otherChoice!
)
// By default a step is skippable
if skippable == false {
questionStep?.isOptional = false
} else {
questionStep?.isOptional = true
}
// setting the placeholder Value if exist any
if Utilities.isValidValue(someObject: placeholderText as AnyObject?) {
questionStep?.placeholder = placeholderText
}
questionStep?.text = text
return questionStep
} else {
return nil
}
case .boolean:
questionStepAnswerFormat = ORKBooleanAnswerFormat()
case .numeric:
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionNumericStyle] as AnyObject?
) {
var maxValue = formatDict?[kStepQuestionNumericMaxValue] as? NSNumber
let minValue = formatDict?[kStepQuestionNumericMinValue] as? NSNumber
if maxValue != nil && maxValue == 0 {
if let minValue = minValue,
!(Int(truncating: minValue) < 0)
{
maxValue = nil // Max value can't be zero if the min value is greater than 0.
}
}
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionNumericPlaceholder] as AnyObject?
) {
placeholderText = formatDict?[kStepQuestionNumericPlaceholder] as? String
}
let localizedQuestionStepAnswerFormatUnit = NSLocalizedString(
(formatDict?[kStepQuestionNumericUnit] as? String)!,
comment: ""
)
let style =
((formatDict?[kStepQuestionNumericStyle] as? String)! == "Decimal")
? 0 : 1
switch ORKNumericAnswerStyle(rawValue: style)! as ORKNumericAnswerStyle {
case .integer: // Integer Question Step
if Utilities.isValidValue(someObject: self.healthDataKey as AnyObject?) {
let quantityTypeId: HKQuantityTypeIdentifier =
HKQuantityTypeIdentifier
.init(
rawValue: self.healthDataKey!
)
let quantityType = HKQuantityType.quantityType(
forIdentifier: quantityTypeId
)
var unit: HKUnit?
// Setting the Unit if valid unit exist
if localizedQuestionStepAnswerFormatUnit != ""
&& self.isUnitValid(
unit: localizedQuestionStepAnswerFormatUnit
)
{
unit = HKUnit.init(from: localizedQuestionStepAnswerFormatUnit)
}
questionStepAnswerFormat = ORKHealthKitQuantityTypeAnswerFormat.init(
quantityType: quantityType!,
unit: unit,
style: ORKNumericAnswerStyle.integer
)
} else {
if minValue != nil || maxValue != nil {
questionStepAnswerFormat = ORKNumericAnswerFormat.init(
style: ORKNumericAnswerStyle.integer,
unit: localizedQuestionStepAnswerFormatUnit,
minimum: minValue,
maximum: maxValue
)
} else {
questionStepAnswerFormat = ORKAnswerFormat.integerAnswerFormat(
withUnit: localizedQuestionStepAnswerFormatUnit
)
}
}
case .decimal: // Decimal Question Step
if Utilities.isValidValue(someObject: self.healthDataKey as AnyObject?) {
let quantityTypeId = HKQuantityTypeIdentifier.init(
rawValue: self.healthDataKey!
)
var unit: HKUnit?
// Setting the Unit if valid unit exist
if localizedQuestionStepAnswerFormatUnit != ""
&& self.isUnitValid(
unit: localizedQuestionStepAnswerFormatUnit
)
{
unit = HKUnit.init(from: localizedQuestionStepAnswerFormatUnit)
}
questionStepAnswerFormat = ORKHealthKitQuantityTypeAnswerFormat.init(
quantityType: HKQuantityType.quantityType(
forIdentifier: quantityTypeId
)!,
unit: unit,
style: ORKNumericAnswerStyle.decimal
)
} else {
if minValue != nil || maxValue != nil {
questionStepAnswerFormat = ORKNumericAnswerFormat.init(
style: ORKNumericAnswerStyle.decimal,
unit: localizedQuestionStepAnswerFormatUnit,
minimum: minValue,
maximum: maxValue
)
} else {
questionStepAnswerFormat = ORKAnswerFormat.decimalAnswerFormat(
withUnit: localizedQuestionStepAnswerFormatUnit
)
}
}
@unknown default:
break
}
} else {
return nil
}
case .timeOfDay:
questionStepAnswerFormat = ORKAnswerFormat.timeOfDayAnswerFormat()
case .date:
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionDateStyle] as AnyObject?
) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
var dateRange: DateRange? = DateRange.defaultValue
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionDateRange] as AnyObject?
) {
dateRange = DateRange.init(
rawValue: (formatDict?[kStepQuestionDateRange] as? String)!
)
}
let defaultDate: NSDate? =
dateFormatter.date(
from: (formatDict?[kStepQuestionDateDefault] as? String)!
) as NSDate?
var minimumDate: NSDate? =
dateFormatter.date(
from: (formatDict?[kStepQuestionDateMinDate] as? String)!
) as NSDate?
var maximumDate: NSDate? =
dateFormatter.date(
from: (formatDict?[kStepQuestionDateMaxDate] as? String)!
) as NSDate?
// Setting the date Range
switch dateRange! {
case .untilCurrent: // Any date less than Current Date
maximumDate = Date.init(timeIntervalSinceNow: 0) as NSDate
case .afterCurrent: // Any date greater than Current
minimumDate = Date.init(timeIntervalSinceNow: 86400) as NSDate
case .defaultValue: break
case .custom: break
}
switch DateStyle(rawValue: (formatDict?[kStepQuestionDateStyle] as? String)!)!
as DateStyle
{
case .date:
questionStepAnswerFormat = ORKAnswerFormat.dateAnswerFormat(
withDefaultDate: defaultDate as Date?,
minimumDate: minimumDate as Date?,
maximumDate: maximumDate as Date?,
calendar: NSCalendar.current
)
case .dateAndTime:
questionStepAnswerFormat = ORKAnswerFormat.dateTime(
withDefaultDate: defaultDate as Date?,
minimumDate: minimumDate as Date?,
maximumDate: maximumDate as Date?,
calendar: NSCalendar.current
)
}
} else {
return nil
}
case .text:
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionTextMultipleLines] as AnyObject?
) {
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionNumericPlaceholder] as AnyObject?
) {
placeholderText = formatDict?[kStepQuestionNumericPlaceholder] as? String
}
var answerFormat = ORKAnswerFormat.textAnswerFormat()
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionTextValidationRegex] as AnyObject?
)
&& Utilities
.isValidValue(
someObject: formatDict?[kStepQuestionTextInvalidMessage] as AnyObject?
)
{
var regex: NSRegularExpression?
regex = try? NSRegularExpression(
pattern: (formatDict?[kStepQuestionTextValidationRegex] as? String)!,
options: []
)
if regex != nil {
answerFormat = ORKAnswerFormat.textAnswerFormat(
withValidationRegularExpression: regex!,
invalidMessage: (formatDict?[kStepQuestionTextInvalidMessage] as? String)!
)
}
} else {
answerFormat.invalidMessage = nil
}
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionTextMaxLength] as AnyObject?
) {
answerFormat.maximumLength = (formatDict?[kStepQuestionTextMaxLength] as? Int)!
} else {
answerFormat.maximumLength = 0
}
answerFormat.multipleLines = (formatDict?[kStepQuestionTextMultipleLines] as? Bool)!
questionStepAnswerFormat = answerFormat
} else {
return nil
}
case .email:
questionStepAnswerFormat = ORKAnswerFormat.emailAnswerFormat()
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionNumericPlaceholder] as AnyObject?
) {
placeholderText = formatDict?[kStepQuestionNumericPlaceholder] as? String
}
case .timeInterval:
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionTimeIntervalStep] as AnyObject?
) {
let defaultTimeInterval: Double?
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionTimeIntervalDefault] as AnyObject?
) {
defaultTimeInterval = Double(
(formatDict?[kStepQuestionTimeIntervalDefault] as? Int)!
)
} else {
defaultTimeInterval = Double(0.0)
}
if (formatDict?[kStepQuestionTimeIntervalStep] as? Int)! >= 1
&& (formatDict?[kStepQuestionTimeIntervalStep] as? Int)! <= 30
{
questionStepAnswerFormat = ORKAnswerFormat.timeIntervalAnswerFormat(
withDefaultInterval: defaultTimeInterval!,
step: (formatDict?[kStepQuestionTimeIntervalStep] as? Int)!
)
} else {
return nil
}
} else {
return nil
}
case .height:
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionHeightMeasurementSystem] as AnyObject?
) {
let measurementSystem: ORKMeasurementSystem?
switch HeightMeasurementSystem(
rawValue: (formatDict?[kStepQuestionHeightMeasurementSystem] as? String)!
)! {
case .local:
measurementSystem = .local
case .metric:
measurementSystem = .metric
case .us:
measurementSystem = .USC
}
questionStepAnswerFormat = ORKAnswerFormat.heightAnswerFormat(
with: measurementSystem!
)
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionNumericPlaceholder] as AnyObject?
) {
placeholderText = formatDict?[kStepQuestionNumericPlaceholder] as? String
}
} else {
return nil
}
case .location:
if Utilities.isValidValue(
someObject: formatDict?[kStepQuestionLocationUseCurrentLocation] as AnyObject?
) {
let answerFormat = ORKAnswerFormat.locationAnswerFormat()
answerFormat.useCurrentLocation = (formatDict?[kStepQuestionLocationUseCurrentLocation] as? Bool)!
questionStepAnswerFormat = answerFormat
} else {
return nil
}
default: break
}
questionStep = ORKQuestionStep(
identifier: key!,
title: title!,
answer: questionStepAnswerFormat
) // TBD: need to verify with API
// By default a step is skippable
if skippable == false {
questionStep?.isOptional = false
}
// setting the placeholder Value if exist any
if Utilities.isValidValue(someObject: placeholderText as AnyObject?) {
questionStep?.placeholder = placeholderText
}
questionStep?.text = text
return questionStep!
} else {
return nil
}
}