Skip to content

Commit

Permalink
Merge pull request #76 from olgadanylova/master
Browse files Browse the repository at this point in the history
Changes
  • Loading branch information
Olha Danylova authored Jun 12, 2019
2 parents 1b2e0a2 + ce90411 commit 2cd490e
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 117 deletions.
4 changes: 2 additions & 2 deletions BackendlessSwift.podspec
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Pod::Spec.new do |s|
s.name = "BackendlessSwift"
s.module_name = "Backendless"
s.version = "0.0.9"
s.source = { :git => 'https://github.com/Backendless/Swift-SDK.git', :tag => '0.0.9' }
s.version = "0.0.10"
s.source = { :git => 'https://github.com/Backendless/Swift-SDK.git', :tag => '0.0.10' }
s.license = { :type => 'MIT', :text => 'Copyright (c) 2013-2019 by Backendless Corp' }
s.homepage = "http://backendless.com"
s.authors = { 'Mark Piller' => '[email protected]', 'Olha Danylova' => '[email protected]' }
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# RELEASE HISTORY

### 0.0.10, / June, 12 2019
* fixed password issue when updating the BackendlessUser object
* fixed Date type issue when retrieving object or registering BackendlessUser with custom Date field
* fixed the BackendlessUser properties methods
* added support of custom smart-text substitutions for push templates:
```
func pushWithTemplate(templateName: String, templateValues: [String : Any], responseHandler: ((MessageStatus) -> Void)!, errorHandler: ((Fault) -> Void)!)
```
* added Channel function:
```
func sendCommand(commandType: String, data: Any?, responseHandler: (() -> Void)!, errorHandler: ((Fault) -> Void)!)
```

### 0.0.9, / June, 6 2019
* added IEmailEnvelope protocol, EmailEnvelope, EnvelopeWithRecepients and EnvelopeWithQuery classes
* added functions to MessagingService:
Expand Down
3 changes: 3 additions & 0 deletions Sources/SwiftSDK/Backendless.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
open func initApp(applicationId: String, apiKey: String) {
self.applicationId = applicationId
self.apiKey = apiKey

// mappings for updating objects correctly
self.data.of(BackendlessUser.self).mapColumn(columnName: "password", toProperty: "_password")
}

open func getApplictionId() -> String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ class BackendlessRequestManager: NSObject {
request.httpBody = (parameters as! String).data(using: .utf8)
}
else {
if var params = parameters as? [String : Any] {
for key in Array(params.keys) {
if let dateParam = params[key] as? Date {
params[key] = dateParam.timeIntervalSince1970
}
}
parameters = params
}
request.httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: [])
}
}
Expand Down
8 changes: 7 additions & 1 deletion Sources/SwiftSDK/Messaging/MessagingService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,13 @@
}

open func pushWithTemplate(templateName: String, responseHandler: ((MessageStatus) -> Void)!, errorHandler: ((Fault) -> Void)!) {
BackendlessRequestManager(restMethod: "messaging/push/\(templateName)", httpMethod: .POST, headers: nil, parameters: nil).makeRequest(getResponse: { response in
pushWithTemplate(templateName: templateName, templateValues: [String : Any](), responseHandler: responseHandler, errorHandler: errorHandler)
}

open func pushWithTemplate(templateName: String, templateValues: [String : Any], responseHandler: ((MessageStatus) -> Void)!, errorHandler: ((Fault) -> Void)!) {
let headers = ["Content-Type": "application/json"]
let parameters = ["templateValues": templateValues]
BackendlessRequestManager(restMethod: "messaging/push/\(templateName)", httpMethod: .POST, headers: headers, parameters: parameters).makeRequest(getResponse: { response in
if let result = self.processResponse.adapt(response: response, to: MessageStatus.self) {
if result is Fault {
errorHandler(result as! Fault)
Expand Down
13 changes: 13 additions & 0 deletions Sources/SwiftSDK/Messaging/RT/Channel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,17 @@
removeCommandListeners()
removeUserStatusListeners()
}

open func sendCommand(commandType: String, data: Any?, responseHandler: (() -> Void)!, errorHandler: ((Fault) -> Void)!) {
let wrappedBlock: (Any) -> () = { response in
responseHandler()
}
if let channelName = self.channelName {
var options = ["channel": channelName, "type": commandType] as [String : Any]
if let data = data {
options["data"] = JSONUtils.shared.objectToJSON(objectToParse: data)
}
RTMethod.shared.sendCommand(type: PUB_SUB_COMMAND, options: options, responseHandler: wrappedBlock, errorHandler: errorHandler)
}
}
}
137 changes: 85 additions & 52 deletions Sources/SwiftSDK/Persistence/PersistenceServiceUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -382,77 +382,104 @@ class PersistenceServiceUtils: NSObject {
return Bundle.main.infoDictionary![kCFBundleNameKey as String] as! String + "." + name
}

func getClassProperties(entity: Any) -> [String] {
// private func getClassProperties(entity: Any) -> [String] {
// let resultClass = type(of: entity) as! NSObject.Type
// var classProperties = [String]()
// var outCount : UInt32 = 0
// if let properties = class_copyPropertyList(resultClass.self, &outCount) {
// for i : UInt32 in 0..<outCount {
// if let key = NSString(cString: property_getName(properties[Int(i)]), encoding: String.Encoding.utf8.rawValue) as String? {
// classProperties.append(key)
// }
// }
// }
// return classProperties
// }

private func getClassPropertiesWithType(entity: Any) -> [String : String] {
let resultClass = type(of: entity) as! NSObject.Type
var classProperties = [String]()
var classProperties = [String : String]()
var outCount : UInt32 = 0
if let properties = class_copyPropertyList(resultClass.self, &outCount) {
for i : UInt32 in 0..<outCount {
if let key = NSString(cString: property_getName(properties[Int(i)]), encoding: String.Encoding.utf8.rawValue) as String? {
classProperties.append(key)
let property = properties[Int(i)]
if let propertyName = String(cString: property_getName(property), encoding: .utf8),
let propertyAttr = property_getAttributes(property) {
let propertyType = String(cString: propertyAttr).components(separatedBy: ",")[0].replacingOccurrences(of: "T", with: "")
classProperties[propertyName] = propertyType
}
}
}
return classProperties
}

func entityToDictionary(entity: Any) -> [String: Any] {
let resultClass = type(of: entity) as! NSObject.Type

var entityDictionary = [String: Any]()
var outCount : UInt32 = 0
if let properties = class_copyPropertyList(resultClass.self, &outCount) {

let entityClassName = getClassName(entity: (entity as! NSObject).classForCoder)
let columnToPropertyMappings = mappings.getColumnToPropertyMappings(className: entityClassName)

for i : UInt32 in 0..<outCount {
if let key = NSString(cString: property_getName(properties[Int(i)]), encoding: String.Encoding.utf8.rawValue) as String?, let value = (entity as! NSObject).value(forKey: key) {

var resultValue = value

if !(value is String), !(value is NSNumber), !(value is NSNull) {
if let arrayValue = value as? [Any] {
var resultArray = [Any]()
for arrayVal in arrayValue {
resultArray.append(entityToDictionaryWithClassProperty(entity: arrayVal))

if let userEntity = entity as? BackendlessUser {
let properties = userEntity.getProperties()
for key in Array(properties.keys) {
entityDictionary[key] = properties[key]
}
}
else {
let resultClass = type(of: entity) as! NSObject.Type
var outCount : UInt32 = 0
if let properties = class_copyPropertyList(resultClass.self, &outCount) {

let entityClassName = getClassName(entity: (entity as! NSObject).classForCoder)
let columnToPropertyMappings = mappings.getColumnToPropertyMappings(className: entityClassName)

for i : UInt32 in 0..<outCount {
if let key = NSString(cString: property_getName(properties[Int(i)]), encoding: String.Encoding.utf8.rawValue) as String?, let value = (entity as! NSObject).value(forKey: key) {

var resultValue = value

if !(value is String), !(value is NSNumber), !(value is NSNull) {
if let arrayValue = value as? [Any] {
var resultArray = [Any]()
for arrayVal in arrayValue {
resultArray.append(entityToDictionaryWithClassProperty(entity: arrayVal))
}
resultValue = resultArray
}
resultValue = resultArray
}
else if let dictionaryValue = value as? [String : Any] {
var resultDictionary = [String : Any]()
for key in dictionaryValue.keys {
if let dictionaryVal = dictionaryValue[key] {
if !(dictionaryVal is String), !(dictionaryVal is NSNumber), !(dictionaryVal is NSNull) {
resultDictionary[key] = entityToDictionaryWithClassProperty(entity: dictionaryVal)
}
else {
resultDictionary[key] = dictionaryVal
else if let dictionaryValue = value as? [String : Any] {
var resultDictionary = [String : Any]()
for key in dictionaryValue.keys {
if let dictionaryVal = dictionaryValue[key] {
if !(dictionaryVal is String), !(dictionaryVal is NSNumber), !(dictionaryVal is NSNull) {
resultDictionary[key] = entityToDictionaryWithClassProperty(entity: dictionaryVal)
}
else {
resultDictionary[key] = dictionaryVal
}
}
}
resultValue = resultDictionary
}
else {
resultValue = entityToDictionaryWithClassProperty(entity: value)
}
resultValue = resultDictionary
}

if let mappedKey = columnToPropertyMappings.getKey(forValue: key) {
entityDictionary[mappedKey] = resultValue
}
else {
resultValue = entityToDictionaryWithClassProperty(entity: value)
entityDictionary[key] = resultValue
}
if let objectId = storedObjects.getObjectId(forObject: entity as! AnyHashable) {
entityDictionary["objectId"] = objectId
}
}

if let mappedKey = columnToPropertyMappings.getKey(forValue: key) {
entityDictionary[mappedKey] = resultValue
}
else {
entityDictionary[key] = resultValue
}
if let objectId = storedObjects.getObjectId(forObject: entity as! AnyHashable) {
entityDictionary["objectId"] = objectId
}
}
}
}
return entityDictionary
}

func entityToDictionaryWithClassProperty(entity: Any) -> [String: Any] {
func entityToDictionaryWithClassProperty(entity: Any) -> [String: Any] {
var entityDictionary = entityToDictionary(entity: entity)
var className = getClassName(entity: type(of: entity))
if let name = className.components(separatedBy: ".").last {
Expand All @@ -477,7 +504,7 @@ class PersistenceServiceUtils: NSObject {
if let objectId = deviceRegistration.objectId {
storedObjects.rememberObjectId(objectId: objectId, forObject: deviceRegistration)
return deviceRegistration
}
}
}
var resultEntityTypeName = ""
let classMappings = mappings.getTableToClassMappings()
Expand All @@ -495,7 +522,7 @@ class PersistenceServiceUtils: NSObject {
}
if let resultEntityType = resultEntityType {
let entity = resultEntityType.init()
let entityFields = getClassProperties(entity: entity)
let entityFields = getClassPropertiesWithType(entity: entity)
let entityClassName = getClassName(entity: entity.classForCoder)

let columnToPropertyMappings = mappings.getColumnToPropertyMappings(className: entityClassName)
Expand All @@ -505,8 +532,8 @@ class PersistenceServiceUtils: NSObject {
if columnToPropertyMappings.keys.contains(dictionaryField) {
entity.setValue(dictionary[dictionaryField], forKey: columnToPropertyMappings[dictionaryField]!)
}
else if entityFields.contains(dictionaryField) {
// process relations
else if Array(entityFields.keys).contains(dictionaryField) {
if let relationDictionary = dictionary[dictionaryField] as? [String: Any] {
let relationClassName = getClassName(className: relationDictionary["___class"] as! String)
if relationDictionary["___class"] as? String == "Users",
Expand All @@ -521,7 +548,6 @@ class PersistenceServiceUtils: NSObject {
entity.setValue(relationObject, forKey: dictionaryField)
}
}

else if let relationArrayOfDictionaries = dictionary[dictionaryField] as? [[String: Any]] {
var relationsArray = [Any]()
for relationDictionary in relationArrayOfDictionaries {
Expand All @@ -540,8 +566,15 @@ class PersistenceServiceUtils: NSObject {
entity.setValue(relationsArray, forKey: dictionaryField)
}
}
else {
entity.setValue(dictionary[dictionaryField], forKey: dictionaryField)
else if let value = dictionary[dictionaryField] {
if let valueType = entityFields[dictionaryField],
valueType.contains("NSDate"),
value is Int {
entity.setValue(dataTypesUtils.intToDate(intVal: value as! Int), forKey: dictionaryField)
}
else {
entity.setValue(value, forKey: dictionaryField)
}
}
}
}
Expand Down
Loading

0 comments on commit 2cd490e

Please sign in to comment.