Skip to content

Commit

Permalink
Merge pull request #8 from thehung111/master
Browse files Browse the repository at this point in the history
Add facets filtering support
  • Loading branch information
thehung111 authored Feb 7, 2017
2 parents f91b6e2 + 8d77355 commit b91f2cc
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 7 deletions.
4 changes: 2 additions & 2 deletions Example/Example/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1</string>
<string>1.2.0</string>
<key>CFBundleVersion</key>
<string>2</string>
<string>3</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
Expand Down
6 changes: 5 additions & 1 deletion Example/Example/SearchViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ class SearchViewController: UIViewController, UITextFieldDelegate, SwiftHUEColor
params!.fl = ["im_url"] // retrieve image url. By default the API only return im_name if does not specify fl parameter
params!.limit = 15 // display 15 results per page

// params?.facets = ["price", "brand"]
// params?.facetsLimit = 10
// params?.facetShowCount = true

ViSearch.sharedInstance.colorSearch( params: params!,
successHandler: {
(data : ViResponseData?) -> Void in
Expand All @@ -162,7 +166,7 @@ class SearchViewController: UIViewController, UITextFieldDelegate, SwiftHUEColor
}
else {
// perform segue here
//dump(data)
// dump(data)
self.recentResponseData = data

DispatchQueue.main.async {
Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- 6.2 [Filtering Results](#62-filtering-results)
- 6.3 [Result Score](#63-result-score)
- 6.4 [Automatic Object Recognition Beta](#64-automatic-object-recognition-beta)
- 6.5 [Facets Filtering](#65-facets-filtering)
7. [Event Tracking](#7-event-tracking)

---
Expand Down Expand Up @@ -564,6 +565,41 @@ params.detection = "bag";

The detected product types are listed in `product_types` together with the match score and box area of the detected object. Multiple objects can be detected from the query image and they are ranked from the highest score to lowest. The full list of supported product types by our API will also be returned in `product_types_list`.

### 6.5 Facets Filtering

You can get the facet results by sending a list of fields to enable faceting on. Here are some limitations on the request:

- Facet fields need to be marked as `searchable` on ViSenze dashboard.
Text field is not supported as facet field even it is `searchable`.
System will return value range, the min, max value for numerical fields which are in ‘int’, ‘float’ type.

- Only facet values that exist in current search results will be returned. For example, if your search results contain 10 unique brands, then the facet filters will return the value for these 10 brands.

- Facet value list is ordered by the item count descendingly.
When the value is set to all (facets = *), all the searchable fields will be used as facet fields.

Name | Type | Description
--- | --- | --- |
facets | array | List of fields to enable faceting.
facets_limit | Int | Limit of the number of facet values to be returned. Only for non-numerical fields.
facets_show_count | Boolean | Option to show the facets count in the response.

```swift
params?.facets = ["price", "brand"]
params?.facetsLimit = 10
params?.facetShowCount = true

// view facet results
ViResponseData.facets

// numerical facet would have a min and max
// ViFacet.min , ViFacet.max

// string fields would have a count (if facetShowCount is set )
// ViFacet.items

```

## 7. Event Tracking

### Send Action For Tracking
Expand Down
4 changes: 2 additions & 2 deletions ViSearchSDK.podspec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Be sure to run `pod spec lint ViSearchSwiftDev.podspec' to ensure this is a
# Be sure to run `pod spec lint ViSearchSwift.podspec' to ensure this is a
# valid spec and to remove all comments including this before submitting the spec.
#
# To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
Expand All @@ -10,7 +10,7 @@ Pod::Spec.new do |s|


s.name = "ViSearchSDK"
s.version = "1.1.0"
s.version = "1.2.0"
s.summary = "A Visual Search API solution (Swift SDK)"

s.description = <<-DESC
Expand Down
8 changes: 8 additions & 0 deletions ViSearchSDK/ViSearchSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
BD50FD621DA8B4220035FD78 /* UIColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD50FD611DA8B4220035FD78 /* UIColorExtension.swift */; };
BD6540571DA6302D00E10162 /* ViUploadSearchParamsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD6540561DA6302D00E10162 /* ViUploadSearchParamsTests.swift */; };
BD65405A1DA63F5200E10162 /* ViSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD6540591DA63F5200E10162 /* ViSearch.swift */; };
BD7020ED1E49BB1D006BAE40 /* ViFacet.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD7020EC1E49BB1D006BAE40 /* ViFacet.swift */; };
BD7020EF1E49BB99006BAE40 /* ViFacetItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD7020EE1E49BB99006BAE40 /* ViFacetItem.swift */; };
BD7DED8C1DA2AFCF00CDF6DE /* ViSearchSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BD7DED821DA2AFCF00CDF6DE /* ViSearchSDK.framework */; };
BD7DED911DA2AFCF00CDF6DE /* ViSearchSDKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD7DED901DA2AFCF00CDF6DE /* ViSearchSDKTests.swift */; };
BD7DED931DA2AFCF00CDF6DE /* ViSearchSDK.h in Headers */ = {isa = PBXBuildFile; fileRef = BD7DED851DA2AFCF00CDF6DE /* ViSearchSDK.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -52,6 +54,8 @@
BD50FD611DA8B4220035FD78 /* UIColorExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UIColorExtension.swift; path = Helper/UIColorExtension.swift; sourceTree = "<group>"; };
BD6540561DA6302D00E10162 /* ViUploadSearchParamsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViUploadSearchParamsTests.swift; sourceTree = "<group>"; };
BD6540591DA63F5200E10162 /* ViSearch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViSearch.swift; sourceTree = "<group>"; };
BD7020EC1E49BB1D006BAE40 /* ViFacet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViFacet.swift; sourceTree = "<group>"; };
BD7020EE1E49BB99006BAE40 /* ViFacetItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViFacetItem.swift; sourceTree = "<group>"; };
BD7DED821DA2AFCF00CDF6DE /* ViSearchSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ViSearchSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BD7DED851DA2AFCF00CDF6DE /* ViSearchSDK.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViSearchSDK.h; sourceTree = "<group>"; };
BD7DED861DA2AFCF00CDF6DE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -176,6 +180,8 @@
BDB1F7CB1DA4E01D000C5EAA /* ViImageResult.swift */,
BDB1F7CD1DA4EA9C000C5EAA /* ViProductType.swift */,
BDB1F7CF1DA4EBBC000C5EAA /* ViProductTypeList.swift */,
BD7020EC1E49BB1D006BAE40 /* ViFacet.swift */,
BD7020EE1E49BB99006BAE40 /* ViFacetItem.swift */,
);
path = Response;
sourceTree = "<group>";
Expand Down Expand Up @@ -311,8 +317,10 @@
BD7DEDB11DA2C2C900CDF6DE /* ViSearchParams.swift in Sources */,
BDB1F7D01DA4EBBC000C5EAA /* ViProductTypeList.swift in Sources */,
BD7DEDAF1DA2C10100CDF6DE /* ViImageSettings.swift in Sources */,
BD7020EF1E49BB99006BAE40 /* ViFacetItem.swift in Sources */,
BD65405A1DA63F5200E10162 /* ViSearch.swift in Sources */,
BD7DEDAB1DA2B6C400CDF6DE /* ViColorSearchParams.swift in Sources */,
BD7020ED1E49BB1D006BAE40 /* ViFacet.swift in Sources */,
BDB1F7CC1DA4E01D000C5EAA /* ViImageResult.swift in Sources */,
BD7DEDA61DA2B14100CDF6DE /* ViBox.swift in Sources */,
BDC096421DA357C8002166B4 /* SettingHelper.swift in Sources */,
Expand Down
15 changes: 15 additions & 0 deletions ViSearchSDK/ViSearchSDK/Classes/Request/ViBaseSearchParams.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ open class ViBaseSearchParams : ViSearchParamsProtocol {
/// Used for automatic object recognition
public var detection : String? = nil

/// List of fields to enable faceting
public var facets : [String] = []

/// Limit of the number of facet values to be returned. Only for non-numerical fields
public var facetsLimit : Int = 10

/// whether to show the facets count in the response.
public var facetShowCount : Bool = false

// MARK: search protocol
public func toDict() -> [String: Any] {
var dict : [String:Any] = [:]
Expand Down Expand Up @@ -98,6 +107,12 @@ open class ViBaseSearchParams : ViSearchParamsProtocol {
dict["fl"] = fl
}

if facets.count > 0 {
dict["facets"] = self.facets
dict["facets_limit"] = self.facetsLimit
dict["facets_show_count"] = self.facetShowCount ? "true" : "false"
}

return dict ;

}
Expand Down
35 changes: 35 additions & 0 deletions ViSearchSDK/ViSearchSDK/Classes/Response/ViFacet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// ViFacet.swift
// ViSearchSDK
//
// Created by Hung on 7/2/17.
// Copyright © 2017 Hung. All rights reserved.
//

import Foundation

open class ViFacet: NSObject {

/// facet field name
public var key : String

/// facet field items for string facets fields
public var items : [ViFacetItem] = []

// for numeric facet, a range will be return instead
public var min: Int? = nil

// for numeric facet, a range with min, max will be returned insted
public var max: Int? = nil

public init(key: String) {
self.key = key
}

public init(key: String, items: [ViFacetItem] ) {
self.key = key
self.items = items
}


}
24 changes: 24 additions & 0 deletions ViSearchSDK/ViSearchSDK/Classes/Response/ViFacetItem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// ViFacetItem.swift
// ViSearchSDK
//
// Created by Hung on 7/2/17.
// Copyright © 2017 Hung. All rights reserved.
//

import Foundation

open class ViFacetItem: NSObject {
public var value : String
public var count : Int? = nil

public init(value: String) {
self.value = value
}

public init(value: String, count: Int?) {
self.value = value
self.count = count
}

}
43 changes: 43 additions & 0 deletions ViSearchSDK/ViSearchSDK/Classes/Response/ViResponseData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ open class ViResponseData: NSObject {
/// for automatic object detection. See http://developers.visenze.com/api/?shell#automatic-object-recognition-beta for details
public var productTypeList : [ViProductTypeList] = []

/// facet results. Refer to http://developers.visenze.com/api/index.php#facet-and-filtering for details
public var facets : [ViFacet] = []

/// store list of error messages if request is not successful
public var error: [String] = []

Expand Down Expand Up @@ -98,6 +101,10 @@ open class ViResponseData: NSObject {
if let pTypeListJson = json["product_types_list"] as? [Any] {
self.productTypeList = ViResponseData.parseProductTypeList(pTypeListJson)
}

if let facetListJson = json["facets"] as? [Any] {
self.facets = ViResponseData.parseFacets(facetListJson)
}

}
catch {
Expand Down Expand Up @@ -139,6 +146,42 @@ open class ViResponseData: NSObject {
return results
}

public static func parseFacets(_ arr: [Any]) -> [ViFacet]{
var results = [ViFacet]()
for jsonItem in arr {
if let dict = jsonItem as? [String:Any] {
let key = dict["key"] as! String
let item = ViFacet(key: key)

// string facet
if let itemArr = dict["items"] as? [Any] {
var facetItems : [ViFacetItem] = []
for itemDict in itemArr {

if let itemDict = itemDict as? [String:Any] {
let val = itemDict["value"] as! String
let count = itemDict["count"] as? Int
let facetItem = ViFacetItem(value: val, count: count)
facetItems.append(facetItem)
}
}
item.items = facetItems
}

// numeric facet
if let range = dict["range"] as? [String: String] {
// extract min and max
item.min = Int(range["min"]!)
item.max = Int(range["max"]!)
}

results.append(item)
}
}

return results
}

// generate image results from the json array
public static func parseResults(_ arr: [Any]) -> [ViImageResult]{
var results = [ViImageResult]()
Expand Down
2 changes: 1 addition & 1 deletion ViSearchSDK/ViSearchSDK/Classes/ViSearchClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ open class ViSearchClient: NSObject, URLSessionDelegate {
public var timeoutInterval : TimeInterval = 10 // how long to timeout request
public var requestSerialization: ViRequestSerialization

public var userAgent : String = "visearch-swift-sdk/1.1.0"
public var userAgent : String = "visearch-swift-sdk/1.2.0"
private static let userAgentHeader : String = "X-Requested-With"

// whether to authenticate by appkey or by access/secret key point
Expand Down
2 changes: 1 addition & 1 deletion ViSearchSDK/ViSearchSDK/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<string>1.2.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
Expand Down

0 comments on commit b91f2cc

Please sign in to comment.