Toggle navigation
Toggle navigation
This project
Loading...
Sign in
open-source
/
warply_sdk_framework
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Authored by
Manos Chorianopoulos
2026-03-17 17:54:09 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
41eaee4c3f62f997ba6fc87a3474670a7ff88581
41eaee4c
1 parent
5fe9d3ca
getStores request
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
164 additions
and
39 deletions
Package.resolved
SwiftWarplyFramework/SwiftWarplyFramework/Core/WarplySDK.swift
SwiftWarplyFramework/SwiftWarplyFramework/Network/Endpoints.swift
SwiftWarplyFramework/SwiftWarplyFramework/models/Merchant.swift
SwiftWarplyFramework/SwiftWarplyFramework/screens/MyRewardsViewController/MyRewardsViewController.swift
Package.resolved
View file @
41eaee4
...
...
@@ -14,17 +14,8 @@
"kind"
:
"remoteSourceControl"
,
"location"
:
"https://github.com/stephencelis/SQLite.swift"
,
"state"
:
{
"revision"
:
"392dd6058624d9f6c5b4c769d165ddd8c7293394"
,
"version"
:
"0.15.4"
}
},
{
"identity"
:
"swift-toolchain-sqlite"
,
"kind"
:
"remoteSourceControl"
,
"location"
:
"https://github.com/swiftlang/swift-toolchain-sqlite"
,
"state"
:
{
"revision"
:
"b626d3002773b1a1304166643e7f118f724b2132"
,
"version"
:
"1.0.4"
"revision"
:
"0a9893ec030501a3956bee572d6b4fdd3ae158a1"
,
"version"
:
"0.12.2"
}
},
{
...
...
SwiftWarplyFramework/SwiftWarplyFramework/Core/WarplySDK.swift
View file @
41eaee4
...
...
@@ -2552,6 +2552,82 @@ public final class WarplySDK {
}
}
// MARK: - Stores
/// Get stores for a specific merchant
/// - Parameters:
/// - language: Language for the stores (optional, defaults to applicationLocale)
/// - merchantUuid: The UUID of the merchant whose stores to retrieve
/// - completion: Completion handler with stores array
/// - failureCallback: Failure callback with error code
public
func
getStores
(
language
:
String
?
=
nil
,
merchantUuid
:
String
?
=
nil
,
completion
:
@escaping
([
MerchantModel
]?)
->
Void
,
failureCallback
:
@escaping
(
Int
)
->
Void
)
{
let
finalLanguage
=
language
??
self
.
applicationLocale
Task
{
do
{
let
endpoint
=
Endpoint
.
getStores
(
language
:
finalLanguage
,
merchantUuid
:
merchantUuid
??
""
)
let
response
=
try
await
networkService
.
requestRaw
(
endpoint
)
await
MainActor
.
run
{
print
(
"🔍 [WarplySDK] getStores raw response:
\(
response
)
"
)
if
response
[
"MAPP_SHOPS-status"
]
as?
Int
==
1
{
let
dynatraceEvent
=
LoyaltySDKDynatraceEventModel
()
dynatraceEvent
.
_eventName
=
"custom_success_get_stores_loyalty"
dynatraceEvent
.
_parameters
=
nil
self
.
postFrameworkEvent
(
"dynatrace"
,
sender
:
dynatraceEvent
)
var
stores
:
[
MerchantModel
]
=
[]
if
let
mappShops
=
response
[
"MAPP_SHOPS"
]
as?
[
String
:
Any
],
let
result
=
mappShops
[
"result"
]
as?
[[
String
:
Any
]]
{
for
item
in
result
{
stores
.
append
(
MerchantModel
(
dictionary
:
item
))
}
}
print
(
"✅ [WarplySDK] getStores loaded
\(
stores
.
count
)
stores"
)
completion
(
stores
)
}
else
{
let
dynatraceEvent
=
LoyaltySDKDynatraceEventModel
()
dynatraceEvent
.
_eventName
=
"custom_error_get_stores_loyalty"
dynatraceEvent
.
_parameters
=
nil
self
.
postFrameworkEvent
(
"dynatrace"
,
sender
:
dynatraceEvent
)
failureCallback
(
-
1
)
}
}
}
catch
{
await
MainActor
.
run
{
print
(
"❌ [WarplySDK] getStores error:
\(
error
)
"
)
self
.
handleError
(
error
,
context
:
"getStores"
,
endpoint
:
"getStores"
,
failureCallback
:
failureCallback
)
}
}
}
}
/// Get stores for a specific merchant (async/await variant)
/// - Parameters:
/// - language: Language for the stores (optional, defaults to applicationLocale)
/// - merchantUuid: The UUID of the merchant whose stores to retrieve
/// - Returns: Array of stores as MerchantModel
/// - Throws: WarplyError if the request fails
public
func
getStores
(
language
:
String
?
=
nil
,
merchantUuid
:
String
?
=
nil
)
async
throws
->
[
MerchantModel
]
{
return
try
await
withCheckedThrowingContinuation
{
continuation
in
getStores
(
language
:
language
,
merchantUuid
:
merchantUuid
,
completion
:
{
stores
in
if
let
stores
=
stores
{
continuation
.
resume
(
returning
:
stores
)
}
else
{
continuation
.
resume
(
throwing
:
WarplyError
.
networkError
)
}
},
failureCallback
:
{
errorCode
in
continuation
.
resume
(
throwing
:
WarplyError
.
unknownError
(
errorCode
))
})
}
}
// MARK: - Articles
/// Get articles (carousel content)
...
...
SwiftWarplyFramework/SwiftWarplyFramework/Network/Endpoints.swift
View file @
41eaee4
...
...
@@ -73,6 +73,7 @@ public enum Endpoint {
case
getMarketPassDetails
case
getMerchants
(
language
:
String
,
categories
:
[
String
],
defaultShown
:
Bool
,
center
:
Double
,
tags
:
[
String
],
uuid
:
String
,
distance
:
Int
,
parentUuids
:
[
String
])
case
getMerchantCategories
(
language
:
String
)
case
getStores
(
language
:
String
,
merchantUuid
:
String
)
// Articles
case
getArticles
(
language
:
String
,
categories
:
[
String
]?)
...
...
@@ -134,7 +135,7 @@ public enum Endpoint {
return
"/user/v5/{appUUID}/logout"
// Standard Context endpoints - /api/mobile/v2/{appUUID}/context/
case
.
getCampaigns
,
.
getAvailableCoupons
,
.
getCouponSets
,
.
getMerchantCategories
,
.
getArticles
:
case
.
getCampaigns
,
.
getAvailableCoupons
,
.
getCouponSets
,
.
getMerchantCategories
,
.
getArticles
,
.
getStores
:
return
"/api/mobile/v2/{appUUID}/context/"
// Authenticated Context endpoints - /oauth/{appUUID}/context
...
...
@@ -167,7 +168,7 @@ public enum Endpoint {
switch
self
{
case
.
register
,
.
changePassword
,
.
resetPassword
,
.
requestOtp
,
.
verifyTicket
,
.
refreshToken
,
.
logout
,
.
getCampaigns
,
.
getCampaignsPersonalized
,
.
getCoupons
,
.
getCouponSets
,
.
getAvailableCoupons
,
.
getMarketPassDetails
,
.
getProfile
,
.
addCard
,
.
getCards
,
.
deleteCard
,
.
getTransactionHistory
,
.
getPointsHistory
,
.
validateCoupon
,
.
redeemCoupon
,
.
retrieveCoupon
,
.
getMerchants
,
.
getMerchantCategories
,
.
getArticles
,
.
sendEvent
,
.
sendDeviceInfo
,
.
getCosmoteUser
,
.
deiLogin
:
.
getMarketPassDetails
,
.
getProfile
,
.
addCard
,
.
getCards
,
.
deleteCard
,
.
getTransactionHistory
,
.
getPointsHistory
,
.
validateCoupon
,
.
redeemCoupon
,
.
retrieveCoupon
,
.
getMerchants
,
.
getMerchantCategories
,
.
get
Stores
,
.
get
Articles
,
.
sendEvent
,
.
sendDeviceInfo
,
.
getCosmoteUser
,
.
deiLogin
:
return
.
POST
case
.
getSingleCampaign
,
.
getNetworkStatus
:
return
.
GET
...
...
@@ -410,6 +411,17 @@ public enum Endpoint {
]
]
// Stores - retrieve stores for a specific merchant
case
.
getStores
(
let
language
,
let
merchantUuid
):
var
shopsParams
:
[
String
:
Any
]
=
[
"language"
:
language
,
"action"
:
"retrieve_stores"
]
if
!
merchantUuid
.
isEmpty
{
shopsParams
[
"merchant_uuid"
]
=
merchantUuid
}
return
[
"shops"
:
shopsParams
]
// Articles - using content structure for DEI API
case
.
getArticles
(
let
language
,
let
categories
):
var
contentParams
:
[
String
:
Any
]
=
[
...
...
@@ -478,7 +490,7 @@ public enum Endpoint {
return
.
userManagement
// Standard Context - /api/mobile/v2/{appUUID}/context/
case
.
getCampaigns
,
.
getAvailableCoupons
,
.
getCouponSets
,
.
getMerchantCategories
,
.
getArticles
:
case
.
getCampaigns
,
.
getAvailableCoupons
,
.
getCouponSets
,
.
getMerchantCategories
,
.
getArticles
,
.
getStores
:
return
.
standardContext
// Authenticated Context - /oauth/{appUUID}/context
...
...
@@ -520,7 +532,7 @@ public enum Endpoint {
// Standard Authentication (loyalty headers only)
case
.
register
,
.
resetPassword
,
.
requestOtp
,
.
getCampaigns
,
.
getAvailableCoupons
,
.
getCouponSets
,
.
refreshToken
,
.
logout
,
.
verifyTicket
,
.
getSingleCampaign
,
.
sendEvent
,
.
sendDeviceInfo
,
.
getMerchants
,
.
getMerchantCategories
,
.
getArticles
,
.
getNetworkStatus
,
.
deiLogin
:
.
getMerchants
,
.
getMerchantCategories
,
.
getArticles
,
.
get
Stores
,
.
get
NetworkStatus
,
.
deiLogin
:
return
.
standard
// Bearer Token Authentication (loyalty headers + Authorization: Bearer)
...
...
SwiftWarplyFramework/SwiftWarplyFramework/models/Merchant.swift
View file @
41eaee4
...
...
@@ -134,30 +134,56 @@ public class MerchantModel {
public
init
(
dictionary
:
[
String
:
Any
])
{
// Parse existing fields
self
.
address
=
dictionary
[
"address"
]
as?
String
?
??
""
self
.
id
=
dictionary
[
"id"
]
as?
String
?
??
""
self
.
store_id
=
dictionary
[
"store_id"
]
as?
String
?
??
""
self
.
name
=
dictionary
[
"name"
]
as?
String
?
??
""
self
.
logo
=
dictionary
[
"logo"
]
as?
String
?
??
""
self
.
website
=
dictionary
[
"website"
]
as?
String
?
??
""
self
.
email
=
dictionary
[
"email"
]
as?
String
?
??
""
self
.
telephone
=
dictionary
[
"telephone"
]
as?
String
?
??
""
self
.
category
=
dictionary
[
"category"
]
as?
String
?
??
""
self
.
description
=
dictionary
[
"description"
]
as?
String
?
??
""
self
.
short_description
=
dictionary
[
"short_description"
]
as?
String
?
??
""
self
.
region
=
dictionary
[
"region"
]
as?
String
?
??
""
self
.
latitude
=
dictionary
[
"latitude"
]
as?
Double
?
??
0.0
self
.
longitude
=
dictionary
[
"longitude"
]
as?
Double
?
??
0.0
self
.
image
=
dictionary
[
"image"
]
as?
String
?
??
""
self
.
active
=
dictionary
[
"active"
]
as?
Bool
?
??
false
self
.
city
=
dictionary
[
"city"
]
as?
String
?
??
""
self
.
country
=
dictionary
[
"country"
]
as?
String
?
??
""
self
.
postal_code
=
dictionary
[
"postal_code"
]
as?
String
?
??
""
self
.
vat
=
dictionary
[
"vat"
]
as?
String
?
??
""
self
.
uuid
=
dictionary
[
"uuid"
]
as?
String
?
??
""
self
.
category_uuid
=
dictionary
[
"category_uuid"
]
as?
String
?
??
""
self
.
created
=
dictionary
[
"created"
]
as?
String
?
??
""
self
.
parent
=
dictionary
[
"parent"
]
as?
String
?
??
""
self
.
address
=
dictionary
[
"address"
]
as?
String
??
""
self
.
id
=
dictionary
[
"id"
]
as?
String
??
""
// store_id may arrive as Int or String
if
let
storeIdInt
=
dictionary
[
"store_id"
]
as?
Int
{
self
.
store_id
=
String
(
storeIdInt
)
}
else
{
self
.
store_id
=
dictionary
[
"store_id"
]
as?
String
??
""
}
self
.
name
=
dictionary
[
"name"
]
as?
String
??
""
self
.
logo
=
dictionary
[
"logo"
]
as?
String
??
""
self
.
website
=
dictionary
[
"website"
]
as?
String
??
""
self
.
email
=
dictionary
[
"email"
]
as?
String
??
""
self
.
telephone
=
dictionary
[
"telephone"
]
as?
String
??
""
self
.
category
=
dictionary
[
"category"
]
as?
String
??
""
self
.
description
=
dictionary
[
"description"
]
as?
String
??
""
self
.
short_description
=
dictionary
[
"short_description"
]
as?
String
??
""
self
.
region
=
dictionary
[
"region"
]
as?
String
??
""
// latitude may arrive as String or Double
if
let
latString
=
dictionary
[
"latitude"
]
as?
String
{
self
.
latitude
=
Double
(
latString
)
??
0.0
}
else
{
self
.
latitude
=
dictionary
[
"latitude"
]
as?
Double
??
0.0
}
// longitude may arrive as String or Double
if
let
lonString
=
dictionary
[
"longitude"
]
as?
String
{
self
.
longitude
=
Double
(
lonString
)
??
0.0
}
else
{
self
.
longitude
=
dictionary
[
"longitude"
]
as?
Double
??
0.0
}
self
.
image
=
dictionary
[
"image"
]
as?
String
??
""
// active may arrive as Int (1/0) or Bool
if
let
activeInt
=
dictionary
[
"active"
]
as?
Int
{
self
.
active
=
activeInt
==
1
}
else
{
self
.
active
=
dictionary
[
"active"
]
as?
Bool
??
false
}
self
.
city
=
dictionary
[
"city"
]
as?
String
??
""
self
.
country
=
dictionary
[
"country"
]
as?
String
??
""
// postal_code may arrive as Int or String
if
let
postalInt
=
dictionary
[
"postal_code"
]
as?
Int
{
self
.
postal_code
=
String
(
postalInt
)
}
else
{
self
.
postal_code
=
dictionary
[
"postal_code"
]
as?
String
??
""
}
self
.
vat
=
dictionary
[
"vat"
]
as?
String
??
""
self
.
uuid
=
dictionary
[
"uuid"
]
as?
String
??
""
self
.
category_uuid
=
dictionary
[
"category_uuid"
]
as?
String
??
""
self
.
created
=
dictionary
[
"created"
]
as?
String
??
""
// parent_uuid key used by stores endpoint; fallback to parent for merchants
self
.
parent
=
dictionary
[
"parent_uuid"
]
as?
String
??
dictionary
[
"parent"
]
as?
String
??
""
self
.
img_preview
=
dictionary
[
"img_preview"
]
as?
String
?
??
""
self
.
admin_name
=
dictionary
[
"admin_name"
]
as?
String
?
??
""
self
.
sorting
=
dictionary
[
"sorting"
]
as?
Int
?
??
0
...
...
SwiftWarplyFramework/SwiftWarplyFramework/screens/MyRewardsViewController/MyRewardsViewController.swift
View file @
41eaee4
...
...
@@ -295,6 +295,26 @@ import UIKit
}
// MARK: - Merchants Loading
// private func loadMerchants() {
// WarplySDK.shared.getStores(merchantUuid: "86eba6980cf746cbbcca5c6446700121") { [weak self] merchants in
// guard let self = self, let merchants = merchants else {
// self?.createCouponSetsSection()
// return
// }
// self.merchants = merchants
// print("✅ [MyRewardsViewController] Loaded \(merchants.count) merchants")
// // Load merchant categories after merchants success
// self.loadMerchantCategories()
// } failureCallback: { [weak self] errorCode in
// print("Failed to load merchants: \(errorCode)")
// self?.createCouponSetsSection()
// }
// }
// TODO: DELETE loadMerchants - No matching needed
private
func
loadMerchants
()
{
// Load merchants from WarplySDK (using enhanced getMerchants method)
WarplySDK
.
shared
.
getMerchants
{
[
weak
self
]
merchants
in
...
...
Please
register
or
login
to post a comment