Virtusize helps retailers to illustrate the size and fit of clothing, shoes and bags online, by letting customers compare the measurements of an item they want to buy (on a retailer's product page) with an item that they already own (a reference item). This is done by comparing the silhouettes of the retailer's product with the silhouette of the customer's reference Item. Virtusize is a widget which opens when clicking on the Virtusize button, which is located next to the size selection on the product page.
Read more about Virtusize at https://www.virtusize.com
You need a unique API key and an Admin account, only available to Virtusize customers. Contact our sales team to become a customer.
This is the integration script for native iOS devices only. For web integration, refer to the developer documentation on https://developers.virtusize.com
- Requirements
- Installation
- Setup
- Virtusize Views
- SwiftUI
- The Order API
- Enable SNS Login in Virtusize for native Webview apps
- Build
- Run all tests
- Roadmap
- License
- iOS 13.0+
- Xcode 12+
- Swift 5.0+
If you'd like to continue using the older Version 1.x.x, refer to the branch v1.
Install using the CocoaPods dependency manager. You can install it with the following command:
$ gem install cocoapods
To integrate Virtusize SDK into your Xcode project using CocoaPods, specify it in your Podfile
:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '13.0'
use_frameworks!
target '<your-target-name>' do
pod 'Virtusize', '~> 2.10.0'
end
Then, run the following command:
$ pod repo update
$ pod install
Starting with the 2.3.2
release, Virtusize supports installation via Swift Package Manager
- In Xcode, select File > Swift Packages > Add Package Dependency... and enter
https://github.com/virtusize/integration_ios.git
as the repository URL. - Select a minimum version of
2.10.0
- Click Next
Install using the Carthage dependency manager. You can install it with the following command:
brew install carthage
To integrate Virtusize SDK into your Xcode project using Carthage, specify it in your Cartfile
:
github "virtusize/integration_ios"
Then, run the following command:
$ carthage update
Follow Carthage
documentation for further instruction on how to link the framework and build it.
Set up the SDK in the App delegate's application(_:didFinishLaunchingWithOptions:)
method.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Virtusize.APIKey is required
Virtusize.APIKey = "15cc36e1d7dad62b8e11722ce1a245cb6c5e6692"
// For using the Order API, Virtusize.userID is required
Virtusize.userID = "123"
// By default, the Virtusize environment will be set to .GLOBAL
Virtusize.environment = .STAGING
Virtusize.params = VirtusizeParamsBuilder()
// By default, the initial language will be set based on the Virtusize environment
.setLanguage(.JAPANESE)
// By default, ShowSGI is false
.setShowSGI(true)
// By default, Virtusize allows all the possible languages including English, Japanese and Korean
.setAllowedLanguages([VirtusizeLanguage.ENGLISH, VirtusizeLanguage.JAPANESE])
// By default, Virtusize displays all the possible info categories in the Product Details tab,
// including "modelInfo", "generalFit", "brandSizing" and "material".
.setDetailsPanelCards([VirtusizeInfoCategory.BRANDSIZING, VirtusizeInfoCategory.GENERALFIT])
// By default, Virtusize disables the SNS buttons
.setShowSNSButtons(true)
// Target the specific environment branch by its name
.setBranch("branch-name")
.build()
return true
}
The environment is the region you are running the integration from, either .STAGING
, .GLOBAL
, .JAPAN
or .korea
You can set up the Virtusize.params
by using VirtusizeParamsBuilder to change the configuration of the integration. Possible configuration methods are shown in the following table:
VirtusizeParamsBuilder
Method | Argument Type | Example | Description | Requirement |
---|---|---|---|---|
setLanguage | VirtusizeLanguage | setLanguage(.JAPANESE) | Sets the initial language that the integration will load in. The possible values are VirtusizeLanguage.ENGLISH , VirtusizeLanguage.JAPANESE and VirtusizeLanguage.KOREAN |
No. By default, the initial language will be set based on the Virtusize environment. |
setShowSGI | Boolean | setShowSGI(true) | Determines whether the integration will fetch SGI and use SGI flow for users to add user generated items to their wardrobe. | No. By default, ShowSGI is set to false |
setAllowedLanguages | A list of VirtusizeLanguage |
setAllowedLanguages([VirtusizeLanguage.ENGLISH, VirtusizeLanguage.JAPANESE]) | The languages that the user can switch to using the Language Selector | No. By default, the integration allows all the possible languages to be displayed, including English, Japanese and Korean. |
setDetailsPanelCards | A list of VirtusizeInfoCategory |
setDetailsPanelCards([VirtusizeInfoCategory.BRANDSIZING, VirtusizeInfoCategory.GENERALFIT]) | The info categories which will be displayed in the Product Details tab. Possible categories are: VirtusizeInfoCategory.MODELINFO , VirtusizeInfoCategory.GENERALFIT , VirtusizeInfoCategory.BRANDSIZING and VirtusizeInfoCategory.MATERIAL |
No. By default, the integration displays all the possible info categories in the Product Details tab. |
setShowSNSButtons | Boolean | setShowSNSButtons(true) | Determines whether the integration will show SNS buttons | No. By default, ShowSNSButtons is set to false |
setBranch | String | setBranch("branch-name") | Targets specific environment branch | No. By default, production environment is targeted. staging - staging environment is targeted. <branch-name> a specific branch is targeted |
You can enable internal logger for debugging purpose by updating App delegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Setup Virtusize LogLevel
VirtusizeLogger.logLevel = .debug // `.none` is default
// Override Virtusize log handler, if necessary
//VirtusizeLogger.logHandler = { logLevel, message in
// print("[Virtusize] \(logLevel): \(message)")
//}
// ... continue Virtusize and App initialization
return true
}
In the view controller for your product page, you will need to use Virtusize.load
to populate the Virtusize views:
- Create a
VirtusizeProduct
object with:- An
exernalId
that will be used to reference the product in the Virtusize server - An
imageURL
for the product image
- An
- Pass the
VirtusizeProduct
object to theVirtusize.load
method
override func viewDidLoad() {
super.viewDidLoad()
// Declare a `VirtusizeProduct` variable, which will be passed to the `Virtusize` views in order to bind the product info
let product = VirtusizeProduct(
// Set the product's external ID
externalId: "vs_dress",
// Set the product image URL
imageURL: URL(string: "http://www.example.com/image.jpg")
)
// Load the product in order to populate the `Virtusize` views
Virtusize.load(product: product)
}
See VirtusizeAuth Setup Guide to enable and configure SNS authentication.
The VirtusizeMessageHandler
protocol has two required methods:
virtusizeController(_:didReceiveError:)
is called when the controller is reporting a network or deserialisation error.virtusizeController(_:didReceiveEvent:)
is called when data is exchanged between the controller and the Virtusize API.VirtusizeEvent
is astruct
with a requiredname
and an optionaldata
property.
extension ViewController: VirtusizeMessageHandler {
func virtusizeController(_ controller: VirtusizeWebViewController?, didReceiveEvent event: VirtusizeEvent) {
print(event)
switch event.name {
case "user-opened-widget":
return
case "user-opened-panel-compare":
return
default:
return
}
}
func virtusizeController(_ controller: VirtusizeWebViewController?, didReceiveError error: VirtusizeError) {
print(error)
}
}
The VirtusizeWebViewController
accepts an optional processPool:WKProcessPool
paramater to allow cookie sharing.
// Optional: Set up WKProcessPool to allow cookie sharing.
Virtusize.processPool = WKProcessPool()
When the button is initialized with an exernalId
, the SDK calls our API to check if the product has been parsed and added to our database.
In order to debug that API call, you can subscribe to the NotificationCenter
and observe two Notification.Name
aliases:
Virtusize.productCheckDidFail
, which receives theUserInfo
containing a message with the cause of the failure.Virtusize.productCheckDidSucceed
that will be sent if the call is succesfull.
If the check fails, the button will be hidden.
You can check the example project to see one possible implementation.
After setting up the SDK, add a VirtusizeView
to allow your customers to find their ideal size.
Virtusize SDK provides two main UI components for clients to use:
VirtusizeButton is the simplest UI Button for our SDK. It opens our application in the web view to support customers finding the right size.
There are two default styles of the Virtusize Button in our Virtusize SDK.
Teal Theme | Black Theme |
---|---|
![]() |
![]() |
If you like, you can also customize the button style.
A. Add the Virtusize Button
-
To use the Virtusize Button on the product page of your store, you can either:
-
Create a UIButton in the Xcode’s Interface Builder Storyboard, set the Custom Class to
VirtusizeButton
in the Identity inspector and ensure the button is hidden when loading. -
Or add the VirtusizeButton programmatically:
let virtusizeButton = VirtusizeButton() view.addSubview(virtusizeButton)
-
In order to use our default styles, set the property style of VirtusizeButton as
VirtusizeViewStyle.TEAL
orVirtusizeViewStyle.BLACK
virtusizeButton.style = .TEAL
-
You can also customize the button's style attributes. For example, the titlelabel's text, height, width, etc.
-
B. Connect the Virtusize button, along with the VirtusizeProduct
**object (which you have passed to ** Virtusize.load
) into the Virtusize API by using the Virtusize.setVirtusizeView
method.
Virtusize.setVirtusizeView(self, virtusizeButton, product: product)
Virtusize InPage is a button that behaves like a start button for our service. The button also behaves as a fitting guide that supports customers to find the right size.
There are two types of InPage in the Virtusize SDK.
InPage Standard | InPage Mini |
---|---|
![]() |
![]() |
-
InPage cannot be implemented together with the Virtusize button. Please pick either InPage or Virtusize button for your online shop.
-
InPage Mini must always be used in combination with InPage Standard.
-
Add a VirtusizeInPageStandard
-
To use the Virtusize InPage Standard on the product page of your store, you can either:
-
Create a UIView in the Xcode’s Interface Builder, then set the Custom Class to
VirtusizeInPageStandard
in the Identity inspector and ensure the view is hidden when loading.Be sure to set up constraints for InPage Standard and then go to the Size inspector -> find Intrinsic Size -> Select Placeholder in order to have the dynamic height dependent on its content.
-
Or add the Virtusize InPage Standard programmatically:
let inPageStandard = VirtusizeInPageStandard() view.addSubview(inPageStandard)
-
-
In order to use our default styles, set the property style of VirtusizeInPageStandard as
VirtusizeViewStyle.TEAL
orVirtusizeViewStyle.BLACK
-
If you'd like to change the background color of the CTA button, you can use the property
inPageStandardButtonBackgroundColor
to set the color// Set the InPage Standard style to VirtusizeStyle.BLACK inPageStandard.style = .BLACK // Set the background color of the CTA button to UIColor.blue inPageStandard.inPageStandardButtonBackgroundColor = UIColor.blue
// Set the InPage Standard style to VirtusizeStyle.TEAL inPageStandard.style = .TEAL // Set the background color of the CTA button to a custom color using ColorLiteral inPageStandard.inPageStandardButtonBackgroundColor = #colorLiteral(red: 0.09803921569, green: 0.09803921569, blue: 0.09803921569, alpha: 1)
-
When you add the VirtusizeInPageStandard programmatically and you'd like to set the horizontal margins between the edges of the app screen and the VirtusizeInPageStandard, you can use
setHorizontalMargin
If you'd like to set a direct width for InPage Standard, use auto layout constraints.
// Set the horizontal margins to 16 inPageStandard.setHorizontalMargin(view: view, margin: 16) // Or set the direct width for InPage Standard programtically inPageStandard.translatesAutoresizingMaskIntoConstraints = false inPageStandard.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true inPageStandard.widthAnchor.constraint(equalToConstant: 350).isActive = true
-
If you'd like to change the font sizes of InPage Standard, you can use the properties
messageFontSize
andbuttonFontSize
.inPageStandard.buttonFontSize = 12 inPageStandard.messageFontSize = 12
-
-
Connect the Virtusize InPage Standard, along with the
VirtusizeProduct
**object (which you have passed to **Virtusize.load
) into the Virtusize API by using theVirtusize.setVirtusizeView
method.Virtusize.setVirtusizeView(self, inPageStandard, product: product)
-
There are two default design variations.
Teal Theme Black Theme -
Here are some possible layouts
1 thumbnail + 2 lines of message 2 thumbnails + 2 lines of message 1 thumbnail + 1 line of message 2 animated thumbnails + 2 lines of message -
-
You can:
- change the background color of the CTA button as long as it passes WebAIM contrast test.
- change the width of InPage so it fits your application width.
-
You cannot:
- change interface components such as shapes and spacing.
- change the font.
- change the CTA button shape.
- change messages.
- change or hide the box shadow.
- hide the footer that contains VIRTUSIZE logo and Privacy Policy text link.
-
This is a mini version of InPage which can be placed in your application. The discreet design is suitable for layouts where customers are browsing product images and size tables.
-
Add a VirtusizeInPageMini
-
To use the Virtusize InPage Mini on the product page of your store, you can either:
-
Create a UIView in the Xcode’s Interface Builder, set the Custom Class to
VirtusizeInPageMini
in the Identity inspector and ensure the view is hidden when loading.Be sure to set up constraints for InPage Mini and then go to the Size inspector -> find Intrinsic Size -> Select Placeholder in order to have the dynamic height dependent on its content.
-
Or add the Virtusize InPage Mini programmatically:
let inPageMini = VirtusizeInPageMini() view.addSubview(inPageMini)
-
-
In order to use our default styles, set the property style of VirtusizeInPageMini as
VirtusizeViewStyle.TEAL
orVirtusizeViewStyle.BLACK
-
If you'd like to change the background color of the bar, you can use the property
inPageMiniBackgroundColor
to set the color.inPageMini.style = .TEAL inPageMini.inPageMiniBackgroundColor = #colorLiteral(red: 0.09803921569, green: 0.09803921569, blue: 0.09803921569, alpha: 1)
-
When you add the VirtusizeInPageMini programtically and you'd like to set up the horizontal margins between the edges of the app screen and the VirtusizeInPageMini, you can use
setHorizontalMargin
If you'd like to set a direct width for InPage Mini, use auto layout constraints.
// Set the horizontal margins to 16 inPageMini.setHorizontalMargin(view: view, margin: 16) // Or set the direct width for InPage Standard programtically inPageMini.translatesAutoresizingMaskIntoConstraints = false inPageMini.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true inPageMini.widthAnchor.constraint(equalToConstant: 350).isActive = true
-
If you'd like to change the font sizes of InPage Mini, you can use the properties
messageFontSize
andbuttonFontSize
.inPageMini.messageFontSize = 12 inPageMini.buttonFontSize = 10
-
-
Connect the Virtusize InPage Mini, along with the
VirtusizeProduct
**object (which you have passed to **Virtusize.load
) into the Virtusize API by using theVirtusize.setVirtusizeView
method.Virtusize.setVirtusizeView(self, inPageMini, product: product)
-
There are two default design variations.
Teal Theme Black Theme -
Underneath the product image Underneath or near the size table -
- Japanese
- Noto Sans JP
- 12pt (Message)
- 10pt (Button)
- Korean
- Noto Sans KR
- 12pt (Message)
- 10pt (Button)
- English
- San Francisco (System Default)
- 14pt (Message)
- 12pt (Button)
- Japanese
-
- You can:
- change the background color of the bar as long as it passes WebAIM contrast test.
- You cannot:
- change the font.
- change the CTA button shape.
- change messages.
- You can:
Check the Set Up section for the example code
@main
struct ExampleApp: App {
init() {
// Initialize Virtusize
Virtusize.APIKey = "api-key"
Virtusize.params = VirtusizeParamsBuilder()
// ... conifgure Virtusize parameters
.build()
}
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL(perform: { url in
// Handle Virtusize SNS callback
_ = Virtusize.handleUrl(url)
})
}
}
}
struct ProductView: View {
init() {
// Set up the product information in order to populate the Virtusize view
Virtusize.product = VirtusizeProduct(
externalId: "vs_dress",
imageURL: URL(string: "http://www.example.com/image.jpg")
)
}
...
}
- SwiftUIVirtusizeButton: is equivalent to Virtusize Button
struct ProductView: View {
var body: some View {
VStack {
SwiftUIVirtusizeButton(
action: {
// Set showVirtusizeWebView to true when the button is clicked
showVirtusizeWebView = true
},
// (Optional) You can customize the button by accessing it here
uiView: { virtusizeButton in
virtusizeButton.setTitle("Check size", for: .normal)
virtusizeButton.backgroundColor = .vsBlackColor
},
// (Optional) You can use our default styles: either Black or Teal for the button.
// If you want to customize the button on your own, please omit defaultStyle
defaultStyle: .BLACK
)
}
}
}
- SwiftUIVirtusizeInPageStandard: is equivalent to InPage Standard
struct ProductView: View {
var body: some View {
VStack {
SwiftUIVirtusizeInPageStandard(
action: {
// Set showVirtusizeWebView to true when the button is clicked
showVirtusizeWebView = true
},
// (Optional): You can customize the button by accessing it here
uiView: { virtusizeInPageStandard in
virtusizeInPageStandard.buttonFontSize = 12
virtusizeInPageStandard.messageFontSize = 12
virtusizeInPageStandard.inPageStandardButtonBackgroundColor = .vsBlackColor
virtusizeInPageStandard.setHorizontalMargin(margin: 16)
},
// (Optional): You can use our default styles either Black or Teal for the InPage Standard view.
// The default is set to .BLACK.
defaultStyle: .BLACK
)
}
}
}
- SwiftUIVirtusizeInPageMini: is equivalent to InPage Mini
struct ProductView: View {
var body: some View {
VStack {
SwiftUIVirtusizeInPageMini(
action: {
// Set showVirtusizeWebView to true when the button is clicked
showVirtusizeWebView = true
},
// (Optional): You can customize the button by accessing it here
uiView: { virtusizeInPageMini in
virtusizeInPageMini.messageFontSize = 12
virtusizeInPageMini.buttonFontSize = 10
virtusizeInPageMini.inPageMiniBackgroundColor = .vsTealColor
virtusizeInPageMini.setHorizontalMargin(margin: 16)
},
// (Optional): You can use our default styles either Black or Teal for the InPage Mini view.
// The default is set to .BLACK.
defaultStyle: .TEAL
)
}
}
}
4. Use SwiftUIVirtusizeViewController to open the Virtusize web view when any of the above components are clicked.
struct ProductView: View {
// Declare a Boolean state to control when to open the Virtusize web view
@State var showVirtusizeWebView = false
var body: some View {
VStack {
SwiftUIVirtusizeButton(
action: {
// Set showVirtusizeWebView to true when the button is clicked
showVirtusizeWebView = true
},
...
)
}
// MARK: SwiftUIVirtusizeViewController
.sheet(isPresented: $showVirtusizeWebView) {
SwiftUIVirtusizeViewController(
// (Optional): Set up WKProcessPool to allow cookie sharing
processPool: WKProcessPool(),
// (Optional): You can use this callback closure to receive Virtusize events
didReceiveEvent: { event in
print(event)
switch event.name {
case "user-opened-widget":
return
case "user-opened-panel-compare":
return
default:
return
}
},
// (Optional): You can use this callback closure to receive Virtusize SDK errors
didReceiveError: { error in
print(error)
}
)
}
}
}
You can set up NotificationCenter listeners with the onReceive modifier to debug the product data check
struct ProductView: View {
var body: some View {
VStack {
SwiftUIVirtusizeButton(
...
)
}
.sheet(isPresented: $showVirtusizeWebView) {
SwiftUIVirtusizeViewController(
...
)
}
// (Optional): You can set up NotificationCenter listeners to debug the product data check
// - `Virtusize.productDataCheckDidFail`, the `UserInfo` will contain a message with the cause of the failure
// - `Virtusize.productDataCheckDidSucceed`
.onReceive(NotificationCenter.default.publisher(for: Virtusize.productDataCheckDidSucceed)) { notification in
print(notification)
}
.onReceive(NotificationCenter.default.publisher(for: Virtusize.productDataCheckDidFail)) { notification in
print(notification)
}
}
}
6. For integrating the other optional features listed below, you can check out the ExampleSwiftUI for a detailed implementation.
- Allow cookie sharing
- Hide the space of the Virtusize SwiftUI components
- Make the Virtusize web view full screen
The order API enables Virtusize to show your customers the items they have recently purchased as part of their Purchase History
, and use those items to compare with new items they want to buy.
Make sure to set up the user ID before sending orders to Virtusize. You can set up the user ID either:
in the application(_:didFinishLaunchingWithOptions:)
method of the App delegate before the app is launched
or
in your view controller after the app is launched
Virtusize.userID = "123"
The VirtusizeOrder structure gets passed to the Virtusize.sendOrder
method, and has the following properties:
Note: * means the property is required
VirtusizeOrder
Property | Data Type | Example | Description |
---|---|---|---|
externalOrderId* | String | "20200601586" | The order ID provided by the client |
items* | An array of VirtusizeOrderItem structures |
See the table below | An array of the order items. |
VirtusizeOrderItem
Sample
var virtusizeOrder = VirtusizeOrder(externalOrderId: "2020060812345")
let item = VirtusizeOrderItem(
externalProductId: "A00001",
size: "L",
sizeAlias: "Large",
variantId: "A00001_SIZEL_RED",
imageUrl: "http://images.example.com/products/A00001/red/image1xl.jpg",
color: "Red",
gender: "W",
unitPrice: 5100.00,
currency: "JPY",
quantity: 1,
url: "http://example.com/products/A00001"
)
virtusizeOrder.items = [item]
Call the Virtusize.sendOrder
method in your activity or fragment when the user places an order.
The onSuccess
and onError
callbacks are optional.
Virtusize.sendOrder(
virtusizeOrder,
// This success callback is optional and gets called when the app successfully sends the order
onSuccess: {
print("Successfully sent the order")
},
// This error callback is optional and gets called when an error occurs
// when the app is sending the order
onError: { error in
print("Failed to send the order, error: \(error.debugDescription)")
})
See VirtusizeAuth for WebView Apps Setup
You need to install SwiftLint.
make build
make test
We use swiftlint for formatting. It's integrated into the XCode build steps. But you can also call it from command line.
# install swiftlint
brew install swiftlint
# run linter
swiftlint
# auto-correct warnings
swiftlint --fix
# or run linter from Makefile
make lint
make lint-fix
Ensure to setup the pre-push
git hooks after cloning the repo.
Git hook will run linter and tests on every push automatically.
make install-git-hooks
We use subset fonts to reduce the overall SDK size.
The subset glyphs are limited to the characters used in the localization files.
Whenever you update the localization files, ensure to regenerate the subset fonts of the SDK.
# Ensure to install FontTools
pip install --upgrade fonttools
sh ./Scripts/build_fonts.sh
Please check the Roadmap to find upcoming features and expected release dates.
Copyright (c) 2018-21 Virtusize CO LTD (https://www.virtusize.jp)