Skip to content
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ let package = Package(
.library(name: "WishKit", targets: ["WishKit"])
],
dependencies: [
.package(url: "https://github.com/wishkit/wishkit-ios-shared.git", exact: "1.4.3")
.package(url: "https://github.com/wishkit/wishkit-ios-shared.git", branch: "private-feedback")
],
targets: [
.target(name: "WishKit", dependencies: [
Expand Down
9 changes: 2 additions & 7 deletions Sources/WishKit/API/Api.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,12 @@ struct Api: RequestCreatable {
}
}

enum ApiResult<Success, Error> {
case success(Success)
case failure(Error)
}

// MARK: - Generic Send Functions

extension Api {
/// Generic Send Function. You need to specify the Result<T, Error> type to help inferring it.
/// e.g: Api.send(request: resetRequest) { (result: Result<ResetPasswordResponse, ApiError.Kind>) in ... }
static func send<T: Decodable>(request: URLRequest, completionHandler: @escaping (ApiResult<T, ApiError>) -> Void) {
static func send<T: Decodable>(request: URLRequest, completionHandler: @escaping (Result<T, ApiError>) -> Void) {
let method = request.httpMethod ?? ""

print("🌐 API | \(method) | \(request.url?.absoluteString ?? "nil")")
Expand Down Expand Up @@ -69,7 +64,7 @@ extension Api {

/// Generic Send Function. You need to specify the Result<T, Error> type to help inferring it.
/// e.g: Api.send(request: resetRequest) { (result: Result<ResetPasswordResponse, ApiError.Kind>) in ... }
static func send<T: Decodable>(request: URLRequest) async -> ApiResult<T, ApiError> {
static func send<T: Decodable>(request: URLRequest) async -> Result<T, ApiError> {
let method = request.httpMethod ?? ""

print("🌐 API | \(method) | \(request.url?.absoluteString ?? "nil")")
Expand Down
8 changes: 4 additions & 4 deletions Sources/WishKit/API/CommentApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ import WishKitShared

struct CommentApi: RequestCreatable {

private static let baseUrl = "\(ProjectSettings.apiUrl)"
private static let baseUrl = ProjectSettings.apiUrl

private static var endpoint = URL(string: "\(baseUrl)/comment")
private static let endpoint = URL(string: "\(baseUrl)/comment")

// MARK: - URLRequests

private static func createComment(_ request: CreateCommentRequest) -> URLRequest? {
guard var url = endpoint else { return nil }
url.appendPathComponent("create")
return createAuthedPOSTReuqest(to: url, with: request)
return createAuthedPOSTRequest(to: url, with: request)
}

static func createComment(request: CreateCommentRequest) async -> ApiResult<CommentResponse, ApiError> {
static func createComment(request: CreateCommentRequest) async -> Result<CommentResponse, ApiError> {

guard let request = createComment(request) else {
return .failure(ApiError(reason: .couldNotCreateRequest))
Expand Down
36 changes: 36 additions & 0 deletions Sources/WishKit/API/PrivateFeedbackApi.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// PrivateFeedbackApi.swift
// wishkit-ios
//
// Created by Martin Lasek on 4/6/24.
// Copyright © 2024 Martin Lasek. All rights reserved.
//

import Foundation
import WishKitShared

struct PrivateFeedbackApi: RequestCreatable {

private static let baseUrl = ProjectSettings.apiUrl

private static let endpoint = URL(string: "\(baseUrl)/private-feedback")

// MARK: - URLRequests

private static func createPrivateFeedback(_ createRequest: CreatePrivateFeedbackRequest) -> URLRequest? {
guard var url = endpoint else { return nil }
url.appendPathComponent("create")
return createAuthedPOSTRequest(to: url, with: createRequest)
}

// MARK: - Api Requests

static func createPrivateFeedback(createRequest: CreatePrivateFeedbackRequest) async -> Result<CreatePrivateFeedbackResponse, ApiError> {

guard let request = createPrivateFeedback(createRequest) else {
return .failure(ApiError(reason: .couldNotCreateRequest))
}

return await Api.send(request: request)
}
}
6 changes: 3 additions & 3 deletions Sources/WishKit/API/RequestCreatable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

protocol RequestCreatable {}
protocol RequestCreatable { }

extension RequestCreatable {

Expand Down Expand Up @@ -44,14 +44,14 @@ extension RequestCreatable {

// MARK: - Authed URLRequests

static func createAuthedPOSTReuqest<T: Encodable>(to url: URL, with body: T) -> URLRequest {
static func createAuthedPOSTRequest<T: Encodable>(to url: URL, with body: T) -> URLRequest {
var request = createPOSTRequest(to: url, with: body)
request.addAuth()
request.addSdkInfo()
return request
}

static func createAuthedGETReuqest(to url: URL) -> URLRequest {
static func createAuthedGETRequest(to url: URL) -> URLRequest {
var request = createGETRequest(to: url)
request.addAuth()
request.addSdkInfo()
Expand Down
8 changes: 4 additions & 4 deletions Sources/WishKit/API/UserApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ import WishKitShared

struct UserApi: RequestCreatable {

private static let baseUrl = "\(ProjectSettings.apiUrl)"
private static let baseUrl = ProjectSettings.apiUrl

private static var endpoint = URL(string: "\(baseUrl)/user")
private static let endpoint = URL(string: "\(baseUrl)/user")

// MARK: - URLRequests

private static func updateUser(_ userRequest: UserRequest) -> URLRequest? {
guard var url = endpoint else { return nil }
url.appendPathComponent("update")
return createAuthedPOSTReuqest(to: url, with: userRequest)
return createAuthedPOSTRequest(to: url, with: userRequest)
}

static func updateUser(userRequest: UserRequest) async -> ApiResult<UserResponse, ApiError> {
static func updateUser(userRequest: UserRequest) async -> Result<UserResponse, ApiError> {

guard let request = updateUser(userRequest) else {
return .failure(ApiError(reason: .couldNotCreateRequest))
Expand Down
59 changes: 38 additions & 21 deletions Sources/WishKit/API/WishApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,68 +9,85 @@
import Foundation
import WishKitShared

protocol WishApiProvider {
func fetchWishList(completion: @escaping (Result<ListWishResponse, ApiError>) -> Void)

func createWish(
createRequest: CreateWishRequest,
completion: @escaping (Result<CreateWishResponse, ApiError>) -> Void
)

func voteWish(
voteRequest: VoteWishRequest,
completion: @escaping (Result<VoteWishResponse, ApiError>) -> Void
)
}

struct WishApi: RequestCreatable {

private static let baseUrl = "\(ProjectSettings.apiUrl)"
private static let baseUrl = ProjectSettings.apiUrl

private static var endpoint = URL(string: "\(baseUrl)/wish")
private static let endpoint = URL(string: "\(baseUrl)/wish")

// MARK: - URLRequests

private static func fetchWishList() -> URLRequest? {
guard var url = endpoint else { return nil }
url.appendPathComponent("list")
return createAuthedGETReuqest(to: url)
return createAuthedGETRequest(to: url)
}

private static func createWish(_ createRequest: CreateWishRequest) -> URLRequest? {
guard var url = endpoint else { return nil }
url.appendPathComponent("create")
return createAuthedPOSTReuqest(to: url, with: createRequest)
return createAuthedPOSTRequest(to: url, with: createRequest)
}

private static func voteWish(_ voteRequest: VoteWishRequest) -> URLRequest? {
guard var url = endpoint else { return nil }
url.appendPathComponent("vote")
return createAuthedPOSTReuqest(to: url, with: voteRequest)
return createAuthedPOSTRequest(to: url, with: voteRequest)
}
}

// MARK: - WishApiProvider

// MARK: - Api Requests
extension WishApi: WishApiProvider {

static func fetchWishList(
completionHandler: @escaping (ApiResult<ListWishResponse, ApiError>) -> Void
func fetchWishList(
completion: @escaping (Result<ListWishResponse, ApiError>) -> Void
) {
guard let request = fetchWishList() else {
completionHandler(.failure(ApiError(reason: .couldNotCreateRequest)))
guard let request = WishApi.fetchWishList() else {
completion(.failure(ApiError(reason: .couldNotCreateRequest)))
return
}

Api.send(request: request, completionHandler: completionHandler)
Api.send(request: request, completionHandler: completion)
}

static func createWish(
func createWish(
createRequest: CreateWishRequest,
completionHandler: @escaping (ApiResult<CreateWishResponse, ApiError>) -> Void
completion: @escaping (Result<CreateWishResponse, ApiError>) -> Void
) {

guard let request = createWish(createRequest) else {
completionHandler(.failure(ApiError(reason: .couldNotCreateRequest)))
guard let request = WishApi.createWish(createRequest) else {
completion(.failure(ApiError(reason: .couldNotCreateRequest)))
return
}

Api.send(request: request, completionHandler: completionHandler)
Api.send(request: request, completionHandler: completion)
}

static func voteWish(
func voteWish(
voteRequest: VoteWishRequest,
completionHandler: @escaping (ApiResult<VoteWishResponse, ApiError>) -> Void
completion: @escaping (Result<VoteWishResponse, ApiError>) -> Void
) {

guard let request = voteWish(voteRequest) else {
completionHandler(.failure(ApiError(reason: .couldNotCreateRequest)))
guard let request = WishApi.voteWish(voteRequest) else {
completion(.failure(ApiError(reason: .couldNotCreateRequest)))
return
}

Api.send(request: request, completionHandler: completionHandler)
Api.send(request: request, completionHandler: completion)
}
}
8 changes: 6 additions & 2 deletions Sources/WishKit/Extensions/ToolbarCompat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@
import SwiftUI

extension View {

@ViewBuilder
/// If the toolBar is placed in a view that's inside a NavigationStack it doesn't work and this is a bug.
func toolbarKeyboardDoneButton() -> some View {
#if canImport(UIKit) && !os(visionOS)
if #available(macOS 13.0, iOS 15, *) {
self.toolbar {
ToolbarItem(placement: .keyboard) {
HStack {
Spacer()
Button(action: { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) }, label: { Text("Done") })

Button(
action: { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) },
label: { Text("Done") }
)
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions Sources/WishKit/Model/AlertModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@ import SwiftUI

final class AlertModel: ObservableObject {

@Published
var showAlert = false

@Published
var alertReason: AlertReason = .none

enum AlertReason {
case alreadyVoted
case alreadyImplemented
case voteReturnedError(String)
case descriptionRequired

case successfullyCreated
case createReturnedError(String)
Expand All @@ -22,10 +29,4 @@ final class AlertModel: ObservableObject {

case none
}

@Published
var showAlert = false

@Published
var alertReason: AlertReason = .none
}
1 change: 1 addition & 0 deletions Sources/WishKit/Model/CommentModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import SwiftUI

final class CommentModel: ObservableObject {

@Published
var newCommentValue = ""

Expand Down
8 changes: 7 additions & 1 deletion Sources/WishKit/Model/WishModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,17 @@ final class WishModel: ObservableObject {
@Published
var hasFetched: Bool = false

let wishApi: WishApiProvider

init(wishApi: WishApiProvider) {
self.wishApi = wishApi
}

@MainActor
func fetchList(completion: (() -> ())? = nil) {
isLoading = true

WishApi.fetchWishList { result in
wishApi.fetchWishList { result in
switch result {
case .success(let response):
DispatchQueue.main.async {
Expand Down
6 changes: 4 additions & 2 deletions Sources/WishKit/ProjectSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import Foundation

struct ProjectSettings {
static var apiUrl: String {

static let apiUrl = {
let wishKitUrl = ProcessInfo.processInfo.environment["wishkit-url"]
return wishKitUrl ?? "https://www.wishkit.io/api"
}
}()

static let sdkVersion = "4.1.1"
}
4 changes: 2 additions & 2 deletions Sources/WishKit/Theme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ extension Theme {
}

/// Convenience function to set ligth and dark mode colors.
static public func `set`(light: Color, dark: Color) -> Scheme {
public static func `set`(light: Color, dark: Color) -> Scheme {
return Scheme(light: light, dark: dark)
}

/// Sets the same color for light and dark mode.
static public func `setBoth`(to color: Color) -> Scheme {
public static func `setBoth`(to color: Color) -> Scheme {
return Scheme(light: color, dark: color)
}
}
Expand Down
Loading