Commit fa853f3c by Dmitry Stepanets

Finished GraphQL module. Started integration to 1Weather app.

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