new getCouponFilters request and MyRewardsViewController sections handling
Showing
4 changed files
with
161 additions
and
4 deletions
| ... | @@ -438,6 +438,7 @@ private final class SDKState { | ... | @@ -438,6 +438,7 @@ private final class SDKState { |
| 438 | var carouselList: [CampaignItemModel] = [] | 438 | var carouselList: [CampaignItemModel] = [] |
| 439 | var marketPassDetails: MarketPassDetailsModel? | 439 | var marketPassDetails: MarketPassDetailsModel? |
| 440 | var supermarketCampaign: CampaignItemModel? | 440 | var supermarketCampaign: CampaignItemModel? |
| 441 | + var couponFilters: CouponFiltersDataModel? | ||
| 441 | 442 | ||
| 442 | private init() {} | 443 | private init() {} |
| 443 | } | 444 | } |
| ... | @@ -2545,6 +2546,77 @@ public final class WarplySDK { | ... | @@ -2545,6 +2546,77 @@ public final class WarplySDK { |
| 2545 | } | 2546 | } |
| 2546 | } | 2547 | } |
| 2547 | 2548 | ||
| 2549 | + /// Get coupon filters via new endpoint | ||
| 2550 | + /// - Parameters: | ||
| 2551 | + /// - language: Optional language code (defaults to applicationLocale) | ||
| 2552 | + /// - completion: Returns the raw response dictionary on success | ||
| 2553 | + /// - failureCallback: Returns error code on failure | ||
| 2554 | + public func getCouponFilters( | ||
| 2555 | + language: String? = nil, | ||
| 2556 | + completion: @escaping (CouponFiltersDataModel?) -> Void, | ||
| 2557 | + failureCallback: @escaping (Int) -> Void | ||
| 2558 | + ) { | ||
| 2559 | + let finalLanguage = language ?? self.applicationLocale | ||
| 2560 | + | ||
| 2561 | + Task { | ||
| 2562 | + do { | ||
| 2563 | + let endpoint = Endpoint.getCouponFilters(language: finalLanguage) | ||
| 2564 | + let response = try await networkService.requestRaw(endpoint) | ||
| 2565 | + | ||
| 2566 | + await MainActor.run { | ||
| 2567 | + print("📥 getCouponFilters response: \(response)") | ||
| 2568 | + | ||
| 2569 | + let dynatraceEvent = LoyaltySDKDynatraceEventModel() | ||
| 2570 | + dynatraceEvent._eventName = "custom_success_couponfilters_loyalty" | ||
| 2571 | + dynatraceEvent._parameters = nil | ||
| 2572 | + self.postFrameworkEvent("dynatrace", sender: dynatraceEvent) | ||
| 2573 | + | ||
| 2574 | + if let resultData = response["result"] as? [String: Any] { | ||
| 2575 | + let filterModel = CouponFiltersDataModel(dictionary: resultData) | ||
| 2576 | + self.setCouponFilters(filterModel) | ||
| 2577 | + completion(filterModel) | ||
| 2578 | + } else { | ||
| 2579 | + completion(nil) | ||
| 2580 | + } | ||
| 2581 | + } | ||
| 2582 | + } catch { | ||
| 2583 | + await MainActor.run { | ||
| 2584 | + let dynatraceEvent = LoyaltySDKDynatraceEventModel() | ||
| 2585 | + dynatraceEvent._eventName = "custom_error_couponfilters_loyalty" | ||
| 2586 | + dynatraceEvent._parameters = nil | ||
| 2587 | + self.postFrameworkEvent("dynatrace", sender: dynatraceEvent) | ||
| 2588 | + | ||
| 2589 | + if let networkError = error as? NetworkError { | ||
| 2590 | + failureCallback(networkError.code) | ||
| 2591 | + } else { | ||
| 2592 | + failureCallback(-1) | ||
| 2593 | + } | ||
| 2594 | + } | ||
| 2595 | + } | ||
| 2596 | + } | ||
| 2597 | + } | ||
| 2598 | + | ||
| 2599 | + /// Get coupon filters (async/await variant) | ||
| 2600 | + /// - Parameters: | ||
| 2601 | + /// - language: Language code for localized content (optional, defaults to applicationLocale) | ||
| 2602 | + /// - Returns: Parsed filters model | ||
| 2603 | + /// - Throws: WarplyError if the request fails | ||
| 2604 | + public func getCouponFilters( | ||
| 2605 | + language: String? = nil | ||
| 2606 | + ) async throws -> CouponFiltersDataModel { | ||
| 2607 | + return try await withCheckedThrowingContinuation { continuation in | ||
| 2608 | + getCouponFilters(language: language, completion: { response in | ||
| 2609 | + if let response = response { | ||
| 2610 | + continuation.resume(returning: response) | ||
| 2611 | + } else { | ||
| 2612 | + continuation.resume(throwing: WarplyError.networkError) | ||
| 2613 | + } | ||
| 2614 | + }, failureCallback: { errorCode in | ||
| 2615 | + continuation.resume(throwing: WarplyError.unknownError(errorCode)) | ||
| 2616 | + }) | ||
| 2617 | + } | ||
| 2618 | + } | ||
| 2619 | + | ||
| 2548 | /// Get available coupons (async/await variant) | 2620 | /// Get available coupons (async/await variant) |
| 2549 | /// - Returns: Dictionary of coupon availability data | 2621 | /// - Returns: Dictionary of coupon availability data |
| 2550 | /// - Throws: WarplyError if the request fails | 2622 | /// - Throws: WarplyError if the request fails |
| ... | @@ -4344,6 +4416,16 @@ public final class WarplySDK { | ... | @@ -4344,6 +4416,16 @@ public final class WarplySDK { |
| 4344 | return state.couponSets | 4416 | return state.couponSets |
| 4345 | } | 4417 | } |
| 4346 | 4418 | ||
| 4419 | + /// Set coupon filters data | ||
| 4420 | + public func setCouponFilters(_ filters: CouponFiltersDataModel) { | ||
| 4421 | + state.couponFilters = filters | ||
| 4422 | + } | ||
| 4423 | + | ||
| 4424 | + /// Get coupon filters data | ||
| 4425 | + public func getCouponFilters() -> CouponFiltersDataModel? { | ||
| 4426 | + return state.couponFilters | ||
| 4427 | + } | ||
| 4428 | + | ||
| 4347 | /// Set seasonal list | 4429 | /// Set seasonal list |
| 4348 | public func setSeasonalList(_ seasonalCoupons: [LoyaltyGiftsForYouPackage]) { | 4430 | public func setSeasonalList(_ seasonalCoupons: [LoyaltyGiftsForYouPackage]) { |
| 4349 | state.seasonalList = seasonalCoupons | 4431 | state.seasonalList = seasonalCoupons | ... | ... |
| ... | @@ -68,6 +68,7 @@ public enum Endpoint { | ... | @@ -68,6 +68,7 @@ public enum Endpoint { |
| 68 | case getCoupons(language: String, couponsetType: String) | 68 | case getCoupons(language: String, couponsetType: String) |
| 69 | case getCouponSets(language: String, active: Bool, visible: Bool, uuids: [String]?) | 69 | case getCouponSets(language: String, active: Bool, visible: Bool, uuids: [String]?) |
| 70 | case getCouponSetsNew(language: String, active: Bool, visible: Bool, region: String?, offerCategory: String?) | 70 | case getCouponSetsNew(language: String, active: Bool, visible: Bool, region: String?, offerCategory: String?) |
| 71 | + case getCouponFilters(language: String) | ||
| 71 | case getAvailableCoupons | 72 | case getAvailableCoupons |
| 72 | 73 | ||
| 73 | // Market & Merchants | 74 | // Market & Merchants |
| ... | @@ -143,7 +144,7 @@ public enum Endpoint { | ... | @@ -143,7 +144,7 @@ public enum Endpoint { |
| 143 | return "/api/mobile/v2/{appUUID}/context/" | 144 | return "/api/mobile/v2/{appUUID}/context/" |
| 144 | 145 | ||
| 145 | // Authenticated Context endpoints - /oauth/{appUUID}/context | 146 | // Authenticated Context endpoints - /oauth/{appUUID}/context |
| 146 | - case .getCampaignsPersonalized, .getCoupons, .getMarketPassDetails, .getProfile, .addCard, .getCards, .deleteCard, .getTransactionHistory, .getPointsHistory, .validateCoupon, .redeemCoupon, .retrieveCoupon, .getCarouselContent, .getCouponSetsNew: | 147 | + case .getCampaignsPersonalized, .getCoupons, .getMarketPassDetails, .getProfile, .addCard, .getCards, .deleteCard, .getTransactionHistory, .getPointsHistory, .validateCoupon, .redeemCoupon, .retrieveCoupon, .getCarouselContent, .getCouponSetsNew, .getCouponFilters: |
| 147 | return "/oauth/{appUUID}/context" | 148 | return "/oauth/{appUUID}/context" |
| 148 | 149 | ||
| 149 | // Session endpoints - /api/session/{sessionUuid} | 150 | // Session endpoints - /api/session/{sessionUuid} |
| ... | @@ -171,7 +172,7 @@ public enum Endpoint { | ... | @@ -171,7 +172,7 @@ public enum Endpoint { |
| 171 | public var method: HTTPMethod { | 172 | public var method: HTTPMethod { |
| 172 | switch self { | 173 | switch self { |
| 173 | case .register, .changePassword, .resetPassword, .requestOtp, .verifyTicket, .refreshToken, .logout, .getCampaigns, .getCampaignsPersonalized, | 174 | case .register, .changePassword, .resetPassword, .requestOtp, .verifyTicket, .refreshToken, .logout, .getCampaigns, .getCampaignsPersonalized, |
| 174 | - .getCoupons, .getCouponSets, .getCouponSetsNew, .getAvailableCoupons, | 175 | + .getCoupons, .getCouponSets, .getCouponSetsNew, .getCouponFilters, .getAvailableCoupons, |
| 175 | .getMarketPassDetails, .getProfile, .addCard, .getCards, .deleteCard, .getTransactionHistory, .getPointsHistory, .validateCoupon, .redeemCoupon, .retrieveCoupon, .getMerchants, .getMerchantCategories, .getStores, .getArticles, .sendEvent, .sendDeviceInfo, .getCosmoteUser, .deiLogin, .getCarouselContent: | 176 | .getMarketPassDetails, .getProfile, .addCard, .getCards, .deleteCard, .getTransactionHistory, .getPointsHistory, .validateCoupon, .redeemCoupon, .retrieveCoupon, .getMerchants, .getMerchantCategories, .getStores, .getArticles, .sendEvent, .sendDeviceInfo, .getCosmoteUser, .deiLogin, .getCarouselContent: |
| 176 | return .POST | 177 | return .POST |
| 177 | case .getSingleCampaign, .getNetworkStatus: | 178 | case .getSingleCampaign, .getNetworkStatus: |
| ... | @@ -314,6 +315,14 @@ public enum Endpoint { | ... | @@ -314,6 +315,14 @@ public enum Endpoint { |
| 314 | "coupon": couponParams | 315 | "coupon": couponParams |
| 315 | ] | 316 | ] |
| 316 | 317 | ||
| 318 | + case .getCouponFilters(let language): | ||
| 319 | + return [ | ||
| 320 | + "coupon": [ | ||
| 321 | + "action": "get_filters", | ||
| 322 | + "language": language | ||
| 323 | + ] | ||
| 324 | + ] | ||
| 325 | + | ||
| 317 | case .getAvailableCoupons: | 326 | case .getAvailableCoupons: |
| 318 | return [ | 327 | return [ |
| 319 | "coupon": [ | 328 | "coupon": [ |
| ... | @@ -523,7 +532,7 @@ public enum Endpoint { | ... | @@ -523,7 +532,7 @@ public enum Endpoint { |
| 523 | return .standardContext | 532 | return .standardContext |
| 524 | 533 | ||
| 525 | // Authenticated Context - /oauth/{appUUID}/context | 534 | // Authenticated Context - /oauth/{appUUID}/context |
| 526 | - case .getCampaignsPersonalized, .getCoupons, .getMarketPassDetails, .getProfile, .addCard, .getCards, .deleteCard, .getTransactionHistory, .getPointsHistory, .validateCoupon, .redeemCoupon, .retrieveCoupon, .getCarouselContent, .getCouponSetsNew: | 535 | + case .getCampaignsPersonalized, .getCoupons, .getMarketPassDetails, .getProfile, .addCard, .getCards, .deleteCard, .getTransactionHistory, .getPointsHistory, .validateCoupon, .redeemCoupon, .retrieveCoupon, .getCarouselContent, .getCouponSetsNew, .getCouponFilters: |
| 527 | return .authenticatedContext | 536 | return .authenticatedContext |
| 528 | 537 | ||
| 529 | // Authentication - /oauth/{appUUID}/login, /oauth/{appUUID}/token | 538 | // Authentication - /oauth/{appUUID}/login, /oauth/{appUUID}/token |
| ... | @@ -565,7 +574,7 @@ public enum Endpoint { | ... | @@ -565,7 +574,7 @@ public enum Endpoint { |
| 565 | return .standard | 574 | return .standard |
| 566 | 575 | ||
| 567 | // Bearer Token Authentication (loyalty headers + Authorization: Bearer) | 576 | // Bearer Token Authentication (loyalty headers + Authorization: Bearer) |
| 568 | - case .changePassword, .getCampaignsPersonalized, .getCoupons, .getMarketPassDetails, .getProfile, .addCard, .getCards, .deleteCard, .getTransactionHistory, .getPointsHistory, .validateCoupon, .redeemCoupon, .retrieveCoupon, .getCarouselContent, .getCouponSetsNew: | 577 | + case .changePassword, .getCampaignsPersonalized, .getCoupons, .getMarketPassDetails, .getProfile, .addCard, .getCards, .deleteCard, .getTransactionHistory, .getPointsHistory, .validateCoupon, .redeemCoupon, .retrieveCoupon, .getCarouselContent, .getCouponSetsNew, .getCouponFilters: |
| 569 | return .bearerToken | 578 | return .bearerToken |
| 570 | 579 | ||
| 571 | // Basic Authentication (loyalty headers + Authorization: Basic) | 580 | // Basic Authentication (loyalty headers + Authorization: Basic) | ... | ... |
| ... | @@ -659,6 +659,72 @@ public class RedeemedSMHistoryModel { | ... | @@ -659,6 +659,72 @@ public class RedeemedSMHistoryModel { |
| 659 | } | 659 | } |
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | +// MARK: - Coupon Filters Models | ||
| 663 | + | ||
| 664 | +public class CouponFiltersDataModel { | ||
| 665 | + private var offer_categories: [CouponOfferCategoryModel]? | ||
| 666 | + private var regions: [String]? | ||
| 667 | + | ||
| 668 | + public init(dictionary: [String: Any]) { | ||
| 669 | + if let regionsArray = dictionary["regions"] as? [Any] { | ||
| 670 | + self.regions = regionsArray.compactMap { $0 as? String } | ||
| 671 | + } else { | ||
| 672 | + self.regions = [] | ||
| 673 | + } | ||
| 674 | + | ||
| 675 | + if let categoriesArray = dictionary["offer_categories"] as? [[String: Any]] { | ||
| 676 | + var tempCategories: [CouponOfferCategoryModel] = [] | ||
| 677 | + for catDict in categoriesArray { | ||
| 678 | + tempCategories.append(CouponOfferCategoryModel(dictionary: catDict)) | ||
| 679 | + } | ||
| 680 | + self.offer_categories = tempCategories | ||
| 681 | + } else { | ||
| 682 | + self.offer_categories = [] | ||
| 683 | + } | ||
| 684 | + } | ||
| 685 | + | ||
| 686 | + public var _offer_categories: [CouponOfferCategoryModel]? { get { return self.offer_categories } } | ||
| 687 | + public var _regions: [String]? { get { return self.regions } } | ||
| 688 | +} | ||
| 689 | + | ||
| 690 | +public class CouponOfferCategoryModel { | ||
| 691 | + private var uuid: String? | ||
| 692 | + private var admin_name: String? | ||
| 693 | + private var name: String? | ||
| 694 | + private var image: String? | ||
| 695 | + private var parent: String? | ||
| 696 | + private var children: [CouponOfferCategoryModel]? | ||
| 697 | + | ||
| 698 | + public init(dictionary: [String: Any]) { | ||
| 699 | + self.uuid = dictionary["uuid"] as? String | ||
| 700 | + self.admin_name = dictionary["admin_name"] as? String | ||
| 701 | + self.name = dictionary["name"] as? String | ||
| 702 | + | ||
| 703 | + if let imgString = dictionary["image"] as? String { | ||
| 704 | + self.image = imgString.trimmingCharacters(in: .whitespacesAndNewlines) | ||
| 705 | + } | ||
| 706 | + | ||
| 707 | + self.parent = dictionary["parent"] as? String | ||
| 708 | + | ||
| 709 | + if let childrenArray = dictionary["children"] as? [[String: Any]] { | ||
| 710 | + var tempChildren: [CouponOfferCategoryModel] = [] | ||
| 711 | + for childDict in childrenArray { | ||
| 712 | + tempChildren.append(CouponOfferCategoryModel(dictionary: childDict)) | ||
| 713 | + } | ||
| 714 | + self.children = tempChildren | ||
| 715 | + } else { | ||
| 716 | + self.children = [] | ||
| 717 | + } | ||
| 718 | + } | ||
| 719 | + | ||
| 720 | + public var _uuid: String { get { return self.uuid ?? "" } } | ||
| 721 | + public var _admin_name: String { get { return self.admin_name ?? "" } } | ||
| 722 | + public var _name: String { get { return self.name ?? "" } } | ||
| 723 | + public var _image: String { get { return self.image ?? "" } } | ||
| 724 | + public var _parent: String { get { return self.parent ?? "" } } | ||
| 725 | + public var _children: [CouponOfferCategoryModel]? { get { return self.children } } | ||
| 726 | +} | ||
| 727 | + | ||
| 662 | // MARK: - String Extension for HTML | 728 | // MARK: - String Extension for HTML |
| 663 | 729 | ||
| 664 | // extension String { | 730 | // extension String { | ... | ... |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment