Commit fa853f3c by Dmitry Stepanets

Finished GraphQL module. Started integration to 1Weather app.

parent 7eb54a69
......@@ -118,6 +118,8 @@
CD6C22F2266780ED00D75659 /* AdConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6C22E626677B4900D75659 /* AdConfigManager.swift */; };
CD6C22F32667815000D75659 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6C22E526677B4900D75659 /* EnvironmentManager.swift */; };
CD71709025FA317700A63C27 /* ForecastTimePeriodView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD71708F25FA317700A63C27 /* ForecastTimePeriodView.swift */; };
CD75009E2701E666003FBC65 /* InMobiGraphQLSource.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD75009D2701E666003FBC65 /* InMobiGraphQLSource.framework */; };
CD75009F2701E666003FBC65 /* InMobiGraphQLSource.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = CD75009D2701E666003FBC65 /* InMobiGraphQLSource.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CD7BF15526203E6900A30DF5 /* RadarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7BF15426203E6900A30DF5 /* RadarViewController.swift */; };
CD7BF1582620410800A30DF5 /* RadarCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7BF1572620410800A30DF5 /* RadarCoordinator.swift */; };
CD7D3189268F33CC000D01FA /* WidgetPromotionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7D3188268F33CC000D01FA /* WidgetPromotionCoordinator.swift */; };
......@@ -301,6 +303,7 @@
CE30E3802668FBE3006DF5CD /* OneWeatherAnalytics.framework in Embed Frameworks */,
CD615F7F265523BD00B717DB /* OneWeatherCore.framework in Embed Frameworks */,
CD3884562657BA8B0070FD6F /* CoreDataStorage.framework in Embed Frameworks */,
CD75009F2701E666003FBC65 /* InMobiGraphQLSource.framework in Embed Frameworks */,
CD3883C32657B6A10070FD6F /* BlendHealthSource.framework in Embed Frameworks */,
CD3884842657BBCC0070FD6F /* DelayedSaveStorage.framework in Embed Frameworks */,
CD5909D126A59AAA00448579 /* OneWeatherUI.framework in Embed Frameworks */,
......@@ -428,6 +431,7 @@
CD6C22E926677BDF00D75659 /* ConfigManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigManager.swift; sourceTree = "<group>"; };
CD6C22ED26677DBC00D75659 /* PushNotificationsManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushNotificationsManager.swift; sourceTree = "<group>"; };
CD71708F25FA317700A63C27 /* ForecastTimePeriodView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastTimePeriodView.swift; sourceTree = "<group>"; };
CD75009D2701E666003FBC65 /* InMobiGraphQLSource.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InMobiGraphQLSource.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CD7BF15426203E6900A30DF5 /* RadarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarViewController.swift; sourceTree = "<group>"; };
CD7BF1572620410800A30DF5 /* RadarCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarCoordinator.swift; sourceTree = "<group>"; };
CD7D3188268F33CC000D01FA /* WidgetPromotionCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetPromotionCoordinator.swift; sourceTree = "<group>"; };
......@@ -590,6 +594,7 @@
CD3883C22657B6A10070FD6F /* BlendHealthSource.framework in Frameworks */,
CD5909D026A59AAA00448579 /* OneWeatherUI.framework in Frameworks */,
CE13B97B2626FB11007CBD4D /* PSMLocationSDK.xcframework in Frameworks */,
CD75009E2701E666003FBC65 /* InMobiGraphQLSource.framework in Frameworks */,
CDFE45BC26566EF50021A29F /* WDTWeatherSource.framework in Frameworks */,
CD3884552657BA8B0070FD6F /* CoreDataStorage.framework in Frameworks */,
CD3884832657BBCC0070FD6F /* DelayedSaveStorage.framework in Frameworks */,
......@@ -1533,6 +1538,7 @@
DBFD169AA2AA6A3CB5B68BB5 /* Frameworks */ = {
isa = PBXGroup;
children = (
CD75009D2701E666003FBC65 /* InMobiGraphQLSource.framework */,
CD5909CF26A59AAA00448579 /* OneWeatherUI.framework */,
CD5181BF269EEB61008E6B04 /* CoreLocation.framework */,
CDEF70E2266E10B600BA40D6 /* OneWeatherCore.framework */,
......
......@@ -31,7 +31,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
......
......@@ -8,6 +8,7 @@
import UIKit
import OneWeatherCore
import InMobiShortsSource
import InMobiGraphQLSource
import OneWeatherAnalytics
import Nuke
......@@ -31,7 +32,7 @@ class ShortsManager {
//Private
private let avgColorQueue = OperationQueue()
private let colorCache = NSCache<NSString, UIColor>()
private let source = InMobiShortSource()
private let source = InMobiGraphQLSource() //InMobiShortSource()
private let log = Logger(componentName: "ShortsManager")
private var isUpdating = false
private init() {}
......
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
</Workspace>
......@@ -8,6 +8,7 @@
import Foundation
import OneWeatherCore
import OneWeatherAnalytics
import UIKit
public enum InMobiGraphQLSourceError: Error {
case badUrl
......@@ -37,83 +38,102 @@ public class InMobiGraphQLSource: ShortSource {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
let dateString = formatter.string(from: Date())
let graphQLString = """
{"query {
weatherCardObjectCollection(where: {
AND: [ { expiredAt_gte: "\(dateString)" } ],
}) {
items {
shortsCategories,
sourceUrl,
buttonText,
publishedAt
mediaArrayObjectCollection {
items {
... on WImageObject {
title,
summary
image
}
}
}
sys {
id
}
}
}
}
{"query":"query { weatherCardObjectCollection(where: { AND: [ { expiredAt_gte: \\"\(dateString)\\" } ], }) { items { shortsCategories, sourceUrl, buttonText, publishedAt mediaArrayObjectCollection { items { ... on WImageObject { title, summary image } } } sys { id } } } }"}
"""
guard let bodyData = graphQLString.data(using: .utf8) else {
completion(nil, InMobiGraphQLSourceError.dataEncodingError("Invalid GraphQL body"))
return
}
request.httpBody = bodyData
let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
self.log.debug("Network response: error \(String(describing: error))")
completion(nil, InMobiGraphQLSourceError.networkError(error))
return
}
do {
// let jsonData = try JSONEncoder().encode(graphQLString)
guard let data = data else {
self.log.debug("Network response: error Invalid data")
completion(nil, InMobiGraphQLSourceError.dataEncodingError("Invalid data"))
guard let bodyData = graphQLString.data(using: .utf8) else {
completion(nil, InMobiGraphQLSourceError.dataEncodingError("Invalid GraphQL body"))
return
}
request.httpBody = bodyData
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .useDefaultKeys
do {
let graphQLResponse = try decoder.decode(GrapQLResponse.self, from: data)
}
catch {
let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
self.log.debug("Network response: error \(String(describing: error))")
completion(nil, InMobiGraphQLSourceError.networkError(error))
return
}
guard let data = data else {
self.log.debug("Network response: error Invalid data")
completion(nil, InMobiGraphQLSourceError.dataEncodingError("Invalid data"))
return
}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(self.formatter)
decoder.keyDecodingStrategy = .useDefaultKeys
do {
let graphQLResponse = try decoder.decode(GrapQLResponse.self, from: data)
let items = graphQLResponse.weatherItems.map{ self.toAppModel(item: $0) }
completion(items, nil)
}
catch {
self.log.error("Parsing error: \(error)")
completion(nil, InMobiGraphQLSourceError.dataEncodingError(error.localizedDescription))
}
}
dataTask.resume()
}
catch {
self.log.error("Encoding error: \(error)")
completion(nil, InMobiGraphQLSourceError.dataEncodingError(error.localizedDescription))
}
dataTask.resume()
}
private func toAppModel(item: WeatherCardItem) -> ShortsItem {
ShortsItem(id: UUID().uuidString,
images: <#T##[ShortsItemImage]#>,
overlayImages: <#T##[ShortsItemImage]#>,
updatedAtInSecs: <#T##TimeInterval#>,
startsAtInSecs: <#T##TimeInterval#>,
endsAtInSecs: <#T##TimeInterval#>,
shareURL: <#T##URL?#>,
title: <#T##String#>,
summaryText: <#T##String#>,
sourceName: <#T##String#>,
heartCount: <#T##Int#>,
shortURL: <#T##URL?#>,
ctaText: <#T##String#>,
ctaURL: <#T##URL?#>,
likeCount: <#T##Int#>,
shareCount: <#T##Int#>)
let lowImageSize = CGSize(width: 440, height: 783)
let highImageSize = CGSize(width: 783, height: 1701)
var overlayImages = [ShortsItemImage]()
var baseImages = [ShortsItemImage]()
for mediaObjectCollectionItem in item.mediaArrayObjectCollection.items {
let image = mediaObjectCollectionItem.image
for overlayImage in image.overlayImage {
overlayImages.append(ShortsItemImage(width: Int(lowImageSize.width),
height: Int(lowImageSize.height),
url: overlayImage.lowresolution))
overlayImages.append(ShortsItemImage(width: Int(highImageSize.width),
height: Int(highImageSize.height),
url: overlayImage.highresolution))
}
for baseImage in image.baseImage {
baseImages.append(ShortsItemImage(width: Int(lowImageSize.width),
height: Int(lowImageSize.height),
url: baseImage.lowresolution))
baseImages.append(ShortsItemImage(width: Int(highImageSize.width),
height: Int(highImageSize.height),
url: baseImage.highresolution))
}
}
return ShortsItem(id: item.id,
images: baseImages,
overlayImages: overlayImages,
updatedAtInSecs: 0,
startsAtInSecs: 0,
endsAtInSecs: 0,
shareURL: item.sourceUrl,
title: item.mediaArrayObjectCollection.items.first?.title ?? "",
summaryText: item.mediaArrayObjectCollection.items.first?.summary ?? "",
sourceName: "",
heartCount: 0,
shortURL: item.sourceUrl,
ctaText: item.buttonText,
ctaURL: item.sourceUrl,
likeCount: 0,
shareCount: 0)
}
}
......@@ -8,5 +8,5 @@
import Foundation
struct MediaArrayObjectCollection: Codable {
let items: [MediaObjectItem]
}
......@@ -7,10 +7,16 @@
import Foundation
private struct Sys: Codable {
let id: String
}
struct WeatherCardItem: Codable {
let shortsCategores: String
var id: String { sys.id }
let shortsCategories: String
let sourceUrl: URL
let buttonText: String
let publishedAt: Date
let mediaArrayObjectCollection: MediaArrayObjectCollection
private let sys: Sys
}
......@@ -80,9 +80,8 @@ public struct ShortsItem {
var image = overlayImages.first
for itemImage in overlayImages {
if CGFloat(itemImage.width) / UIScreen.main.scale >= width {
if CGFloat(itemImage.width) >= width {
image = itemImage
break
}
}
return image
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment