Skip to content

Commit

Permalink
Merge from master
Browse files Browse the repository at this point in the history
  • Loading branch information
rleojoseph committed Aug 28, 2023
2 parents 115f7b9 + 2a873bb commit e1ccd80
Show file tree
Hide file tree
Showing 20 changed files with 221 additions and 59 deletions.
19 changes: 0 additions & 19 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ jobs:
- run:
name: Build Simulator
command: fastlane build_sim_ci
- run:
name: Execute Tests
command: fastlane ci
- persist_to_workspace:
root: .
paths:
Expand Down Expand Up @@ -135,13 +132,6 @@ jobs:
when: always
command: rm ../MiniApp-Secrets.xcconfig || true

release-candidate-merge-pr:
<<: *container_medium
steps:
- run:
name: PR for Candidate Merge to Master
command: fastlane candidate_pr

release-sdk:
<<: *container_medium
steps:
Expand Down Expand Up @@ -245,15 +235,6 @@ workflows:
ignore: /.*/
- generate-and-publish-documentation:
name: "Generate and Publish Doc"
requires:
- Release SDK
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/
- release-candidate-merge-pr:
name: "PR for Candidate Merge to Master"
requires:
- Release SDK
filters:
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/candidate_pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Create Candidate Pull Request

on:
release:
types: [published]

jobs:
build:
runs-on: macos-latest
steps:
- name: Create PR
run: gh pr create -B candidate -H master --title 'Candidate PR after release ' --body 'Pull request to merge changes from Candidate to master after release'
3 changes: 1 addition & 2 deletions .github/workflows/fastlane.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and Test using Fastlane
name: Build, Test and Upload report

on:
push:
Expand All @@ -25,7 +25,6 @@ jobs:
steps:
- name: Repository checkout
uses: actions/checkout@v2

- name: Setup ruby
uses: ruby/setup-ruby@v1
with:
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
## CHANGELOG

### 5.4.0 (2023-08-29)
**SDK**
- **Feature:** Added a new interface `downloadMiniApp(appId:versionId:completionHandler:)` to download Miniapp from platform in background if needed.
- **Feature:** Added a utility method to know if Miniapp has beend downloaded properly. `isMiniAppCacheAvailable(appId: String, versionId:)`
- **Refactor:** Updated unzip Miniapp method with optional completion handler that will let the host app know if the download is success. `unzipMiniApp(fileName:miniAppId:versionId:completionHandler:)`

**Sample App**
- **Feature:** Added Menu in list view to Download and check if Miniapp is downloaded already.

### 5.3.1 (2023-08-02)
**SDK**
- **Feature:** Updated `loadFromBundle(miniAppManifest:completionHandler)` interface with optional MiniAppManifest object.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import SwiftUI
import MiniApp

struct MiniAppListRowCell: View {

@State var iconUrl: URL?
@State var displayName: String
@State var miniAppId: String
@State var versionTag: String
@State var versionId: String
@State var listType: ListType
@State private var showingAlert = false
@State private var alertDescription = "false"

var body: some View {
HStack {
Expand All @@ -17,6 +22,9 @@ struct MiniAppListRowCell: View {
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 40, height: 40, alignment: .center)
.contextMenu {
menuItems
}
}, placeholder: {
Rectangle()
.fill(Color(.systemGray3))
Expand All @@ -25,6 +33,9 @@ struct MiniAppListRowCell: View {
} else {
RemoteImageView(urlString: iconUrl?.absoluteString ?? "")
.frame(width: 60, height: 40, alignment: .center)
.contextMenu {
menuItems
}
}
Spacer()
}
Expand All @@ -50,17 +61,53 @@ struct MiniAppListRowCell: View {
Spacer()
}
}
.alert(isPresented: $showingAlert) {
Alert(
title: Text("Info"),
message: Text(alertDescription),
dismissButton: .default(Text("OK")))
}
.padding(10)
}
}

var menuItems: some View {
Group {
Button("Download", action: downloadMiniAppInBackground)
Button("Available already?", action: isMiniAppCacheAvailable)
}
}

func downloadMiniAppInBackground() {
MiniApp.shared(with: ListConfiguration(listType: listType).sdkConfig).downloadMiniApp(appId: miniAppId, versionId: versionId) { result in
switch result {
case .success:
print("Download Completed")
case .failure(let error):
print("Error downloading Miniapp:", error)
}
}
}

func isMiniAppCacheAvailable() {
if MiniApp.isMiniAppCacheAvailable(appId: miniAppId, versionId: versionId) {
showingAlert = true
alertDescription = "MiniApp is available"
} else {
showingAlert = true
alertDescription = "MiniApp is not downloaded"
}
}
}

struct MiniAppListRowCell_Previews: PreviewProvider {
static var previews: some View {
MiniAppListRowCell(
displayName: "MiniApp Sample",
miniAppId: "123",
versionTag: "0.7.2",
versionId: "abcdefgh-12345678-abcdefgh-12345678"
versionId: "abcdefgh-12345678-abcdefgh-12345678",
listType: .listI
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,10 @@ extension MiniAppListView {
MiniAppListRowCell(
iconUrl: info.icon,
displayName: info.displayName ?? "",
miniAppId: info.id,
versionTag: info.version.versionTag,
versionId: info.version.versionId
versionId: info.version.versionId,
listType: viewModel.type
)
}
}
Expand Down
2 changes: 1 addition & 1 deletion MiniApp.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |miniapp|
miniapp.name = 'MiniApp'
miniapp.version = '5.3.1'
miniapp.version = '5.4.0'
miniapp.authors = "Rakuten Ecosystem Mobile"
miniapp.summary = "Rakuten's Mini App SDK"
miniapp.description = "This open-source library allows you to integrate Mini App ecosystem into your iOS applications. Mini App SDK also facilitates communication between a mini app and the host app via a message bridge."
Expand Down
4 changes: 2 additions & 2 deletions MiniAppCarthage/MiniApp/MiniApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1332,7 +1332,7 @@
"@executable_path/Frameworks",
);
MACH_O_TYPE = staticlib;
MARKETING_VERSION = 5.3.1;
MARKETING_VERSION = 5.4.0;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = com.rakuten.tech.mobile.MiniApp;
PRODUCT_NAME = MiniApp;
Expand Down Expand Up @@ -1361,7 +1361,7 @@
"@executable_path/Frameworks",
);
MACH_O_TYPE = staticlib;
MARKETING_VERSION = 5.3.1;
MARKETING_VERSION = 5.4.0;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = com.rakuten.tech.mobile.MiniApp;
PRODUCT_NAME = MiniApp;
Expand Down
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
"repositoryURL": "https://github.com/googleads/swift-package-manager-google-mobile-ads.git",
"state": {
"branch": null,
"revision": "78f4c64d0f1900e54529e4c78075d663ca67d6e0",
"version": "9.14.0"
"revision": "a6e24f2167295d95371bfc3049e47381a73a9e43",
"version": "10.7.0"
}
},
{
Expand Down
24 changes: 23 additions & 1 deletion Sources/Classes/core/Downloader/MiniAppDownloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class MiniAppDownloader: MiniAppDownloaderInterface {
}
}

private func download(appId: String, versionId: String, completionHandler: @escaping (Result<URL, MASDKError>) -> Void) {
internal func download(appId: String, versionId: String, completionHandler: @escaping (Result<URL, MASDKError>) -> Void) {
let miniAppStoragePath = FileManager.getMiniAppVersionDirectory(with: appId, and: versionId)
self.manifestDownloader.fetchManifest(apiClient: self.miniAppClient, appId: appId, versionId: versionId) { (result) in
switch result {
Expand All @@ -78,6 +78,28 @@ class MiniAppDownloader: MiniAppDownloaderInterface {
}
}

internal func downloadMiniApp(appId: String, versionId: String, completionHandler: @escaping (Result<URL, MASDKError>) -> Void) {
let miniAppStoragePath = FileManager.getMiniAppVersionDirectory(with: appId, and: versionId)
self.manifestDownloader.fetchManifest(apiClient: self.miniAppClient, appId: appId, versionId: versionId) { (result) in
switch result {
case .success(let responseData):
self.startDownloadingFiles(urls: responseData.manifest, to: miniAppStoragePath, miniAppId: appId, miniAppVersion: versionId) { downloadResult in
switch downloadResult {
case .success:
DispatchQueue.main.async {
self.cacheVerifier.storeHash(for: appId, version: versionId)
}
fallthrough
default:
completionHandler(downloadResult)
}
}
case .failure(let error):
completionHandler(.failure(error))
}
}
}

func isMiniAppAlreadyDownloaded(appId: String, versionId: String) -> Bool {
if miniAppStatus.isDownloaded(appId: appId, versionId: versionId) {
let versionDirectory = FileManager.getMiniAppVersionDirectory(with: appId, and: versionId)
Expand Down
31 changes: 28 additions & 3 deletions Sources/Classes/core/MiniApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import UIKit

/// Mini App Public API methods
public class MiniApp: NSObject {
public static let version = "5.3.1"
public static let version = "5.4.0"
private static let shared = MiniApp()
private let realMiniApp = RealMiniApp()
public static var MAOrientationLock: UIInterfaceOrientationMask = []
Expand Down Expand Up @@ -206,8 +206,33 @@ public class MiniApp: NSObject {
try? MiniAppSecureStorage.wipeSecureStorage(for: miniAppId)
}

public static func unzipMiniApp(fileName: String, miniAppId: String, versionId: String) {
MiniAppSDKUtility.unzipMiniApp(fileName: fileName, miniAppId: miniAppId, versionId: versionId)
/// Unzip the provided archive file from bundle.
/// - Parameters:
/// - fileName: File name of the Bundle that you want to extract in MiniApp folder
/// - miniAppId: MiniApp ID
/// - versionId: Version ID
/// - completionHandler: Status of the Unzip feature
public static func unzipMiniApp(fileName: String, miniAppId: String, versionId: String, completionHandler: ((Result<Bool, MASDKError>) -> Void)? = nil) {
MiniAppSDKUtility.unzipMiniApp(fileName: fileName, miniAppId: miniAppId, versionId: versionId, completionHandler: completionHandler)
}

/// Download a specific MiniApp from the Platform, please note that the MiniApp should be available before start downloading
/// - Parameters:
/// - appId: MiniApp ID
/// - versionId: VersionID of the MiniApp
/// - completionHandler: Completion handler that tells the status of the download
public func downloadMiniApp(appId: String, versionId: String, completionHandler: @escaping (Result<Bool, MASDKError>) -> Void) {
realMiniApp.downloadMiniApp(appId: appId, versionId: versionId, completionHandler: completionHandler)
}

/// Check and return TRUE if the MiniApp is available for a given MiniAppID and VersionID.
/// This method not only checks if the folder is available, but also checks if index.html is available.
/// - Parameters:
/// - appId: MiniApp ID
/// - versionId: VersionID of the MiniApp
/// - Returns: TRUE if MiniApp is available
public static func isMiniAppCacheAvailable(appId: String, versionId: String) -> Bool {
return MiniAppSDKUtility.isMiniAppAvailable(appId: appId, versionId: versionId)
}
}

Expand Down
17 changes: 17 additions & 0 deletions Sources/Classes/core/RealMiniApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,23 @@ internal class RealMiniApp {
completionHandler(.failure(.miniAppCorrupted))
}
}

func downloadMiniApp(appId: String, versionId: String, completionHandler: @escaping (Result<Bool, MASDKError>) -> Void) {
if appId.isEmpty {
return completionHandler(.failure(.invalidAppId))
}
if versionId.isEmpty {
return completionHandler(.failure(.invalidVersionId))
}
miniAppDownloader.downloadMiniApp(appId: appId, versionId: versionId) { result in
switch result {
case .success:
completionHandler(.success(true))
case .failure(let error):
completionHandler(.failure(error))
}
}
}
}

extension RealMiniApp: MiniAppMessageDelegate {
Expand Down
27 changes: 25 additions & 2 deletions Sources/Classes/core/Utilities/MiniAppSDKUtility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,39 @@ import Foundation
import CommonCrypto

class MiniAppSDKUtility {
internal static func unzipMiniApp(fileName: String, miniAppId: String, versionId: String) {
internal static func unzipMiniApp(fileName: String, miniAppId: String, versionId: String, completionHandler: ((Result<Bool, MASDKError>) -> Void)? = nil) {
let cacheVerifier = MiniAppCacheVerifier()
guard let filePath = Bundle.main.url(forResource: fileName, withExtension: "zip") else {
completionHandler?(.failure(.unknownError(domain: MASDKLocale.localize(.unknownError), code: 1, description: "MiniApp Bundle Zip file not found")))
return
}
do {
try FileManager.default.unzipItem(at: filePath, to: FileManager.getMiniAppVersionDirectory(with: miniAppId, and: versionId), skipCRC32: true)
cacheVerifier.storeHash(for: miniAppId, version: versionId)
return
} catch let err {
MiniAppLogger.e("error unzipping archive", err)
MiniAppLogger.e("Error unzipping archive", err)
completionHandler?(.failure(.unknownError(domain: MASDKLocale.localize(.unknownError), code: 1, description: "Failed to Unzip Miniapp with Error: \(err)")))
return
}
}

internal static func cleanMiniAppVersions(appId: String, exceptForVersionId: String) {
guard !appId.isEmpty, !exceptForVersionId.isEmpty else {
return
}
MiniAppStorage.cleanVersions(for: appId, differentFrom: exceptForVersionId)
}

internal static func isMiniAppAvailable(appId: String, versionId: String) -> Bool {
guard !appId.isEmpty, !versionId.isEmpty else {
return false
}
let versionDirectory = FileManager.getMiniAppVersionDirectory(with: appId, and: versionId)
let miniAppRootPath = "\(versionDirectory.path)/\(Constants.rootFileName)"
if FileManager.default.fileExists(atPath: miniAppRootPath) {
return true
}
return false
}
}
11 changes: 11 additions & 0 deletions Sources/Classes/core/View/MiniAppView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ public class MiniAppView: UIView, MiniAppViewable {
case let .success(webView):
self?.state.send(.active)
self?.setupWebView(webView: webView)
self?.cleanVersions()
completion(.success(true))
case let .failure(error):
self?.state.send(.error(error))
Expand All @@ -194,6 +195,16 @@ public class MiniAppView: UIView, MiniAppViewable {
}
}

/// This method will clean all versions of MiniApp except for the version that is passed/loaded
internal func cleanVersions() {
guard let versionId = miniAppHandler.version, !versionId.isEmpty else {
return
}
if !miniAppHandler.appId.isEmpty {
MiniAppSDKUtility.cleanMiniAppVersions(appId: miniAppHandler.appId, exceptForVersionId: versionId)
}
}

public var alertInfo: CloseAlertInfo? {
return miniAppHandler.miniAppShouldClose()
}
Expand Down
Loading

0 comments on commit e1ccd80

Please sign in to comment.