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
2 changes: 1 addition & 1 deletion .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ coverage:
status:
patch:
default:
target: 62
target: auto
changes: false
project:
default:
Expand Down
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# Parse-Swift Changelog

### main
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.6.0...main)
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.7.0...main)
* _Contributing to this repo? Add info about your change here to be included in the next release_

### 1.7.0
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.6.0...1.7.0)

__Improvements__
- Add emailVerified to ParseUser. Make relative query take a QueryConstraint as an argument. Add more documentation ([#129](https://github.com/parse-community/Parse-Swift/pull/129)), thanks to [Corey Baker](https://github.com/cbaker6).

### 1.6.0
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.5.1...1.6.0)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct User: ParseUser {
//: These are required for `ParseUser`.
var username: String?
var email: String?
var emailVerified: Bool?
var password: String?
var authData: [String: [String: String]?]?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,7 @@ query.first { results in
}

//: Query based on relative time. Have to be using mongoDB.
let queryRelative = GameScore.query(relative(key: "createdAt",
comparator: .lessThan,
time: "10 minutes ago"))
/*let queryRelative = GameScore.query(relative("createdAt" < "10 minutes ago"))
queryRelative.find { results in
switch results {
case .success(let scores):
Expand All @@ -98,6 +96,7 @@ queryRelative.find { results in
assertionFailure("Error querying: \(error)")
}
}
*/

let querySelect = query.select("score")
querySelect.first { results in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct User: ParseUser {
//: These are required for `ParseUser`.
var username: String?
var email: String?
var emailVerified: Bool?
var password: String?
var authData: [String: [String: String]?]?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ struct User: ParseUser {
//: These are required for `ParseUser`.
var username: String?
var email: String?
var emailVerified: Bool?
var password: String?
var authData: [String: [String: String]?]?

//: Your custom keys.
var customKey: String?
var score: GameScore?
var targetScore: GameScore?
var allScores: [GameScore]?
}

//: Create your own value typed `ParseObject`.
Expand Down Expand Up @@ -90,6 +92,7 @@ User.login(username: "hello", password: "world") { results in
User.current?.customKey = "myCustom"
User.current?.score = GameScore(score: 12)
User.current?.targetScore = GameScore(score: 100)
User.current?.allScores = [GameScore(score: 5), GameScore(score: 8)]
User.current?.save { results in

switch results {
Expand Down
2 changes: 1 addition & 1 deletion ParseSwift.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "ParseSwift"
s.version = "1.6.0"
s.version = "1.7.0"
s.summary = "Parse Pure Swift SDK"
s.homepage = "https://github.com/parse-community/Parse-Swift"
s.authors = {
Expand Down
16 changes: 8 additions & 8 deletions ParseSwift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2337,7 +2337,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.6.0;
MARKETING_VERSION = 1.7.0;
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
PRODUCT_NAME = ParseSwift;
SKIP_INSTALL = YES;
Expand All @@ -2361,7 +2361,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.6.0;
MARKETING_VERSION = 1.7.0;
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
PRODUCT_NAME = ParseSwift;
SKIP_INSTALL = YES;
Expand Down Expand Up @@ -2427,7 +2427,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 1.6.0;
MARKETING_VERSION = 1.7.0;
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
PRODUCT_NAME = ParseSwift;
SDKROOT = macosx;
Expand All @@ -2453,7 +2453,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 1.6.0;
MARKETING_VERSION = 1.7.0;
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
PRODUCT_NAME = ParseSwift;
SDKROOT = macosx;
Expand Down Expand Up @@ -2600,7 +2600,7 @@
INFOPLIST_FILE = "ParseSwift-watchOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.6.0;
MARKETING_VERSION = 1.7.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-watchOS";
Expand Down Expand Up @@ -2629,7 +2629,7 @@
INFOPLIST_FILE = "ParseSwift-watchOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.6.0;
MARKETING_VERSION = 1.7.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-watchOS";
PRODUCT_NAME = ParseSwift;
Expand All @@ -2656,7 +2656,7 @@
INFOPLIST_FILE = "ParseSwift-tvOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.6.0;
MARKETING_VERSION = 1.7.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-tvOS";
Expand Down Expand Up @@ -2684,7 +2684,7 @@
INFOPLIST_FILE = "ParseSwift-tvOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.6.0;
MARKETING_VERSION = 1.7.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-tvOS";
PRODUCT_NAME = ParseSwift;
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,7 @@ Run `carthage update`, and you should now have the latest version of ParseSwift

After installing ParseSwift, to use it first `import ParseSwift` in your AppDelegate.swift and then add the following code in your `application:didFinishLaunchingWithOptions:` method:
```swift
ParseSwift.initialize(applicationId: "xxxxxxxxxx", clientKey: "xxxxxxxxxx", serverURL: URL(string: "https://example.com")!, liveQueryServerURL: URL(string: "https://example.com")!, authentication: ((URLAuthenticationChallenge,
(URLSession.AuthChallengeDisposition,
URLCredential?) -> Void) -> Void))
ParseSwift.initialize(applicationId: "xxxxxxxxxx", clientKey: "xxxxxxxxxx", serverURL: URL(string: "https://example.com")!)
```
Please checkout the [Swift Playground](https://github.com/parse-community/Parse-Swift/tree/main/ParseSwift.playground) for more usage information.

Expand Down
2 changes: 1 addition & 1 deletion Scripts/jazzy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ bundle exec jazzy \
--author_url http://parseplatform.org \
--github_url https://github.com/parse-community/Parse-Swift \
--root-url http://parseplatform.org/Parse-Swift/api/ \
--module-version 1.6.0 \
--module-version 1.7.0 \
--theme fullwidth \
--skip-undocumented \
--output ./docs/api \
Expand Down
1 change: 1 addition & 0 deletions Sources/ParseSwift/Coding/ParseCoding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import Foundation

// MARK: ParseCoding
/// Custom coding for Parse objects.
public enum ParseCoding {}

// MARK: Coders
Expand Down
47 changes: 36 additions & 11 deletions Sources/ParseSwift/Coding/ParseEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,30 @@ extension Dictionary: _JSONStringDictionaryEncodableMarker where Key == String,
// swiftlint:disable cyclomatic_complexity

// MARK: ParseEncoder
/// An object that encodes Parse instances of a data type as JSON objects.
public struct ParseEncoder {
let dateEncodingStrategy: JSONEncoder.DateEncodingStrategy?

public enum SkippedKeys {
/// Keys to skip during encoding.
public enum SkipKeys {
/// Skip keys for `ParseObject`'s.
case object
/// Skip keys for `ParseCloud` functions or jobs.
case cloud
/// Do not skip any keys.
case none
/// Skip keys for `ParseObject`'s when using custom `objectId`'s.
case customObjectId
/// Specify a custom set of keys to skip.
case custom(Set<String>)

func keys() -> Set<String> {
switch self {

case .object:
return Set(["createdAt", "updatedAt", "objectId", "className"])
return Set(["createdAt", "updatedAt", "objectId", "className", "emailVerified"])
case .customObjectId:
return Set(["createdAt", "updatedAt", "className"])
return Set(["createdAt", "updatedAt", "className", "emailVerified"])
case .cloud:
return Set(["functionJobName"])
case .none:
Expand All @@ -83,14 +90,19 @@ public struct ParseEncoder {
}

func encode(_ value: Encodable) throws -> Data {
let encoder = _ParseEncoder(codingPath: [], dictionary: NSMutableDictionary(), skippingKeys: SkippedKeys.none.keys())
let encoder = _ParseEncoder(codingPath: [], dictionary: NSMutableDictionary(), skippingKeys: SkipKeys.none.keys())
if let dateEncodingStrategy = dateEncodingStrategy {
encoder.dateEncodingStrategy = dateEncodingStrategy
}
return try encoder.encodeObject(value, collectChildren: false, objectsSavedBeforeThisOne: nil, filesSavedBeforeThisOne: nil).encoded
}

public func encode<T: ParseType>(_ value: T, skipKeys: SkippedKeys) throws -> Data {
/**
Encodes an instance of the indicated `ParseType`.
- parameter value: The `ParseType` instance to encode.
- parameter skipKeys: The set of keys to skip during encoding.
*/
public func encode<T: ParseType>(_ value: T, skipKeys: SkipKeys) throws -> Data {
let encoder = _ParseEncoder(codingPath: [], dictionary: NSMutableDictionary(), skippingKeys: skipKeys.keys())
if let dateEncodingStrategy = dateEncodingStrategy {
encoder.dateEncodingStrategy = dateEncodingStrategy
Expand All @@ -104,9 +116,9 @@ public struct ParseEncoder {
filesSavedBeforeThisOne: [UUID: ParseFile]?) throws -> (encoded: Data, unique: Set<UniqueObject>, unsavedChildren: [Encodable]) {
let keysToSkip: Set<String>!
if !ParseSwift.configuration.allowCustomObjectId {
keysToSkip = SkippedKeys.object.keys()
keysToSkip = SkipKeys.object.keys()
} else {
keysToSkip = SkippedKeys.customObjectId.keys()
keysToSkip = SkipKeys.customObjectId.keys()
}
let encoder = _ParseEncoder(codingPath: [], dictionary: NSMutableDictionary(), skippingKeys: keysToSkip)
if let dateEncodingStrategy = dateEncodingStrategy {
Expand All @@ -121,9 +133,9 @@ public struct ParseEncoder {
filesSavedBeforeThisOne: [UUID: ParseFile]?) throws -> (encoded: Data, unique: Set<UniqueObject>, unsavedChildren: [Encodable]) {
let keysToSkip: Set<String>!
if !ParseSwift.configuration.allowCustomObjectId {
keysToSkip = SkippedKeys.object.keys()
keysToSkip = SkipKeys.object.keys()
} else {
keysToSkip = SkippedKeys.customObjectId.keys()
keysToSkip = SkipKeys.customObjectId.keys()
}
let encoder = _ParseEncoder(codingPath: [], dictionary: NSMutableDictionary(), skippingKeys: keysToSkip)
if let dateEncodingStrategy = dateEncodingStrategy {
Expand Down Expand Up @@ -344,40 +356,51 @@ private struct _ParseEncoderKeyedEncodingContainer<Key: CodingKey>: KeyedEncodin

// MARK: - KeyedEncodingContainerProtocol Methods
mutating func encodeNil(forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) { return }
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
container[key.stringValue] = NSNull()
}
mutating func encode(_ value: Bool, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: Int, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: Int8, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: Int16, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: Int32, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: Int64, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: UInt, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: UInt8, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: UInt16, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: UInt32, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: UInt64, forKey key: Key) throws {
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.container[key.stringValue] = self.encoder.box(value)
}
mutating func encode(_ value: String, forKey key: Key) throws {
Expand All @@ -386,20 +409,22 @@ private struct _ParseEncoderKeyedEncodingContainer<Key: CodingKey>: KeyedEncodin
}
mutating func encode(_ value: Float, forKey key: Key) throws {
// Since the float may be invalid and throw, the coding path needs to contain this key.
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.encoder.codingPath.append(key)
defer { self.encoder.codingPath.removeLast() }
self.container[key.stringValue] = try self.encoder.box(value)
}

mutating func encode(_ value: Double, forKey key: Key) throws {
// Since the double may be invalid and throw, the coding path needs to contain this key.
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }
self.encoder.codingPath.append(key)
defer { self.encoder.codingPath.removeLast() }
self.container[key.stringValue] = try self.encoder.box(value)
}

mutating func encode<T>(_ value: T, forKey key: Key) throws where T: Encodable {
if self.encoder.skippedKeys.contains(key.stringValue) { return }
if self.encoder.skippedKeys.contains(key.stringValue) && !self.encoder.ignoreSkipKeys { return }

var valueToEncode: Encodable = value
if let parseObject = value as? Objectable {
Expand Down
1 change: 1 addition & 0 deletions Sources/ParseSwift/Internal/BaseParseUser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ internal struct BaseParseUser: ParseUser {
var authData: [String: [String: String]?]?
var username: String?
var email: String?
var emailVerified: Bool?
var password: String?
var objectId: String?
var createdAt: Date?
Expand Down
6 changes: 6 additions & 0 deletions Sources/ParseSwift/Objects/ParseUser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ public protocol ParseUser: ParseObject {
*/
var email: String? { get set }

/**
Determines if the email is verified for the `ParseUser`.
- note: This value can only be changed on the Parse Server.
*/
var emailVerified: Bool? { get }

/**
The password for the `ParseUser`.

Expand Down
2 changes: 1 addition & 1 deletion Sources/ParseSwift/ParseConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

enum ParseConstants {
static let parseVersion = "1.6.0"
static let parseVersion = "1.7.0"
static let hashingKey = "parseSwift"
static let fileManagementDirectory = "parse/"
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
Expand Down
2 changes: 2 additions & 0 deletions Sources/ParseSwift/Protocols/Objectable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import Foundation

/// The base protocol for a `ParseObject`.
/// - note: You should not use this directly and instead use `ParseObject`.
public protocol Objectable: ParseType, Decodable {
/**
The class name of the object.
Expand Down
2 changes: 2 additions & 0 deletions Sources/ParseSwift/Types/ParseACL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ public struct ParseACL: ParseType, Decodable, Equatable, Hashable {
An enum specifying read and write access controls.
*/
public enum Access: String, Codable, CodingKey {
/// Read access control.
case read
/// Write access control.
case write

public init(from decoder: Decoder) throws {
Expand Down
Loading