Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions wrappers/swift/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
out
25 changes: 25 additions & 0 deletions wrappers/swift/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.15)

PROJECT(Swift_Wrapper)

message("${CMAKE_CURRENT_SOURCE_DIR}")

enable_language(Swift)

# TODO: add logic to build dependencies

include_directories(
../../lib/include/public/
../../lib/include/mat/
)

get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
message(STATUS "dir='${dir}'")
endforeach()

# Add source files to the target
set(PLATFORM_FILES main.swift SDWEventProperties.swift)
set(CMAKE_Swift_FLAGS "${CMAKE_Swift_FLAGS} -import-objc-header Swift_Wrapper-Bridging-Header.h")
add_executable(swift_sample ${PLATFORM_FILES})
target_link_libraries(swift_sample)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't add any extra property, is it necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you asking about the last line? it i used to create the final exe by linking all the libs.

285 changes: 285 additions & 0 deletions wrappers/swift/SDWEventProperties.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//

/**
Represents Event's properties.
*/
public class EventProperties {
/// Event Name.
private var name: String
/// Event priority.
private var priority: ODWEventPriority = ODWEventPriority.unspecified
/// Event properties, Key being the name of the property and Value is property value.
private var _properties: [String: Any] = [:]
var properties: [String: Any] {
get {
return Dictionary(uniqueKeysWithValues: _properties.lazy.map { ($0, $1) })
}
}
/// Event PII (Personal Identifiable Information) tags, Key being property name and Value is PIIKind value.
private var _piiTags: [String: ODWPiiKind] = [:]
var piiTags : [String: ODWPiiKind] {
get {
return Dictionary(uniqueKeysWithValues: _piiTags.lazy.map { ($0, $1) })
}
}
/// Base type of an event.
private var eventType: String = String()

private func setPiiTag(_ name: String, withPiiKind piiKind: ODWPiiKind) {
self._piiTags[name] = piiKind
}

/**
Constructs EventProperties object with event name.

- Parameters:
- name: Name of the event.
*/
public init(name: String!) {
self.name = name
}

/**
Constructs EventProperties object with event name and initial properties.

- Parameters:
- name: Name of the event.
- properties: Initial properties dictionary.
*/
public init(name: String!, properties: [String: Any]!) {
self.name = name
self._properties = properties
}

/**
Constructs EventProperties object with event name, initial properties and PII tags.

- Parameters:
- name: Name of the event.
- properties: Initial properties dictionary.
- piiTags: Initial PII tags.
*/
public init(name: String!, withProperties properties: [String: Any]!, withPiiTags piiTags: [String: ODWPiiKind]!) {
self.name = name
self._properties = properties
self._piiTags = piiTags
self.priority = .unspecified
}

/**
Sets the base type of the event, populated in Records.Type.

- Parameters:
- type: Type of the event.
*/
public func setType(_ type: String) {
self.eventType = type
}

/**
Sets a string property for an event.

- Parameters:
- name: Name of the property
- value: Value of the property.
*/
public func setProperty(_ name: String, withValue value: Any) {
self._properties[name] = value
}

/**
Sets a property for an event with PII tags.

- Parameters:
- name: Name of the property.
- value: Value of the property.
- piiKind: The kind of Personal Identifieable Information (PII), one from the ::ODWPiiKind enum values.
*/
public func setProperty(_ name: String, withValue value: Any, withPiiKind piiKind: ODWPiiKind) {
self.setProperty(name, withValue: value)
self.setPiiTag(name, withPiiKind: piiKind)
}

/**
Sets a double property for an event.

- Parameters:
- name: Name of the property.
- value: A Double that contains the property value.
*/
public func setProperty(_ name: String, withDoubleValue value: Double) {
self._properties[name] = value
}

/**
Sets a double property for an event with PiiTags.

- Parameters:
- name: Name of the property.
- value: A Double that contains the property value.
- piiKind: The kind of Personal Identifieable Information (PII), one from the ::ODWPiiKind enum values.
*/
public func setProperty(_ name: String, withDoubleValue value: Double, withPiiKind piiKind: ODWPiiKind) {
self.setProperty(name, withDoubleValue:value)
self.setPiiTag(name, withPiiKind:piiKind)
}

/**
Sets an integer property value for an event.

- Parameters:
- name: Name of the property.
- value: An integer that contains the property value.
*/
public func setProperty(_ name: String, withInt64Value value: Int64) {
self._properties[name] = value
}

/**
Sets an integer property value for an event with PiiTags.

- Parameters:
- name: Name of the property.
- value: An integer that contains the property value.
- piiKind: The kind of Personal Identifieable Information (PII), one from the ::ODWPiiKind enum values.
*/
public func setProperty(_ name: String, withInt64Value value: Int64, withPiiKind piiKind: ODWPiiKind) {
self.setProperty(name, withInt64Value:value)
self.setPiiTag(name, withPiiKind:piiKind)
}

/**
Sets an integer property value for an event.

- Parameters:
- name: Name of the property.
- value: An integer that contains the property value.
*/
public func setProperty(_ name: String, withUInt8Value value: UInt8) {
self._properties[name] = value
}

/**
Sets an integer property value for an event with PiiTags.

- Parameters:
- name: Name of the property.
- value: An integer that contains the property value.
- piiKind: The kind of Personal Identifieable Information (PII), one from the ::ODWPiiKind enum values.
*/
public func setProperty(_ name: String, withUInt8Value value: UInt8, withPiiKind piiKind: ODWPiiKind) {
self.setProperty(name, withUInt8Value:value)
self.setPiiTag(name, withPiiKind: piiKind)
}

/**
Sets an integer property value for an event.

- Parameters:
- name: Name of the property.
- value: An integer that contains the property value.
*/
public func setProperty(_ name: String, withUInt64Value value: UInt64) {
self._properties[name] = value
}

/**
Sets an integer property value for an event with PiiTags.

- Parameters:
- name: Name of the property.
- value: An integer that contains the property value.
- piiKind: The kind of Personal Identifieable Information (PII), one from the ::ODWPiiKind enum values.
*/
public func setProperty(_ name: String, withUInt64Value value: UInt64, withPiiKind piiKind: ODWPiiKind) {
self.setProperty(name, withUInt64Value:value)
self.setPiiTag(name, withPiiKind:piiKind)
}

/**
Sets a Bool property value for an event.

- Parameters:
- name: Name of the property.
- value: A Bool that contains the property value.
*/
public func setProperty(_ name: String, withBoolValue value: Bool) {
self._properties[name] = value
}

/**
Sets a Bool property value along with PiiTags.

- Parameters:
- name: Name of the property.
- value: A Bool that contains the property value.
- piiKind: The kind of Personal Identifieable Information (PII), one from the ::ODWPiiKind enum values.
*/
public func setProperty(_ name: String, withBoolValue value: Bool, withPiiKind piiKind: ODWPiiKind) {
self.setProperty(name, withBoolValue:value)
self.setPiiTag(name, withPiiKind:piiKind)
}

/**
Sets a UUID property for an event.

- Parameters:
- name: Name of the property.
- value: A UUID that contains the property value.
*/
public func setProperty(_ name: String, withUUIDValue value: UUID) {
self._properties[name] = value
}

/**
Sets a UUID property for an event.

- Parameters:
- name: Name of the property.
- value: A UUID that contains the property value.
- piiKind: The kind of Personal Identifieable Information (PII), one from the ::ODWPiiKind enum values.
*/
public func setProperty(_ name: String, withUUIDValue value: UUID, withPiiKind piiKind: ODWPiiKind) {
self.setProperty(name, withUUIDValue:value)
self.setPiiTag(name, withPiiKind:piiKind)
}

/**
Sets a date property for an event.

- Parameters:
- name: Name of the property.
- value: A Date that contains the property value.
*/
public func setProperty(_ name: String, withDateValue value: Date) {
self._properties[name] = value
}

/**
Sets a date property for an event with PiiTags.

- Parameters:
- name: Name of the property.
- value: A Date that contains the property value.
- piiKind: The kind of Personal Identifieable Information (PII), one from the ::ODWPiiKind enum values.
*/
public func setProperty(_ name: String, withDateValue value: Date, withPiiKind piiKind: ODWPiiKind) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we are using the obj-c definitions ( e.g. ODWPiiKind ) in swift code, are there any interoperability issues between obj-c and swift that the app developer be aware of - E.g. interoperability across Swift compiler version and Obj-c runtime version etc. And as I understand, we can't avoid obj-c usage eventually, as the C++ code can't be directly called from swift ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the point.
Yes, we have to access c++ via objc from swift.

Though I haven't noticed any interoperability issues while building and running the code. However there are minor changes when it comes to using the enum declared in objc from swift, such as Enum prefix name is removed while using. But since they are minor, i thought of keep using the objc enums rather than creating their duplicate in swift.
also, i have create a task to investigate more about the different compiler and version compatibility between swift-objc and update the source files accordingly.

self.setProperty(name, withDateValue:value)
self.setPiiTag(name, withPiiKind:piiKind)
}

/**
Sets privacy metadat for an event.

- Parameters:
- privTags: Privacy data type of the event.
- privLevel: Privacy diagnostic level of the event.
*/
public func setPrivacyMetadata(_ privTags: ODWPrivacyDataType, withdWDiagLevel privLevel: ODWDiagLevel) {
self.setProperty("EventInfo.PrivTags", withUInt64Value:UInt64(privTags.rawValue))
self.setProperty("EventInfo.Level", withUInt8Value:UInt8(privLevel.rawValue))
}
}
10 changes: 10 additions & 0 deletions wrappers/swift/Swift_Wrapper-Bridging-Header.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//

// Contains all the Obj-C header files which are exposed to Swift

#import <Foundation/Foundation.h>

#import "../obj-c/ODWEventProperties.h"
7 changes: 7 additions & 0 deletions wrappers/swift/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

export PATH=/usr/local/bin:$PATH
mkdir out
cd out
cmake .. -G Xcode # Generate swift project files for xcode
xcodebuild -quiet
10 changes: 10 additions & 0 deletions wrappers/swift/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//

let props = EventProperties(name:"TestEvent")
props.setProperty("PropName", withValue: ["Type":"SwiftWrappers"])
props.setProperty("PropWithPII", withInt64Value: Int64(30), withPiiKind: ODWPiiKind.distinguishedName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are consumers going to use Obj-C constants/enums, or are you going to setup new ones for Swift?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am intending to let consumers use the obj-c enums instead of creating new ones in swift

print (props.properties)
print (props.piiTags)