├── README.md ├── LICENSE └── ArgAppUpdater.swift /README.md: -------------------------------------------------------------------------------- 1 | # Check Swift application Update. 2 | 3 | ## There are 2 way to update app. 4 | 5 | 6 | 1. User Confirmation Method 7 | 2. Force Method 8 | 9 | > By user confirmation Method name is 10 | 11 | **showUpdateWithConfirmation()** 12 | 13 | > By Force Method name is 14 | 15 | **showUpdateWithForce()** 16 | 17 | 18 | ## Now let's see how to call this method 19 | 20 | 21 | > if you want to user Confirmation Then Try This 👇🏻 22 | 23 | **ArgAppUpdater.getSingleton().showUpdateWithConfirmation()** 24 | 25 | ![img_2968](https://user-images.githubusercontent.com/6472263/43183229-09700046-9002-11e8-8548-1aa1dd446b33.PNG) 26 | 27 | 28 | > if you want to Force Method Then Try This 👇🏻 29 | 30 | **ArgAppUpdater.getSingleton().showUpdateWithForce()** 31 | 32 | ![img_2969](https://user-images.githubusercontent.com/6472263/43183234-0c248ee2-9002-11e8-8a62-f703477969fd.PNG) 33 | 34 | *Note: This is compltely free for any user. Anyone can Change the code or logic* 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Anup Gupta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ArgAppUpdater.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArgAppUpdater.swift 3 | // Sorion 4 | // 5 | // Created by Anup Gupta on 04/04/18. 6 | // Copyright © 2018 GeekGuns. All rights reserved. 7 | // 8 | 9 | 10 | import UIKit 11 | 12 | enum VersionError: Error { 13 | case invalidBundleInfo, invalidResponse 14 | } 15 | 16 | class LookupResult: Decodable { 17 | var results: [AppInfo] 18 | } 19 | 20 | class AppInfo: Decodable { 21 | var version: String 22 | var trackViewUrl: String 23 | //let identifier = Bundle.main.infoDictionary?["CFBundleIdentifier"] as? String, 24 | // You can add many thing based on "http://itunes.apple.com/lookup?bundleId=\(identifier)" response 25 | // here version and trackViewUrl are key of URL response 26 | // so you can add all key beased on your requirement. 27 | 28 | } 29 | 30 | class ArgAppUpdater: NSObject { 31 | private static var _instance: ArgAppUpdater?; 32 | 33 | private override init() { 34 | 35 | } 36 | 37 | public static func getSingleton() -> ArgAppUpdater { 38 | if (ArgAppUpdater._instance == nil) { 39 | ArgAppUpdater._instance = ArgAppUpdater.init(); 40 | } 41 | return ArgAppUpdater._instance!; 42 | } 43 | 44 | private func getAppInfo(completion: @escaping (AppInfo?, Error?) -> Void) -> URLSessionDataTask? { 45 | guard let identifier = Bundle.main.infoDictionary?["CFBundleIdentifier"] as? String, 46 | let url = URL(string: "http://itunes.apple.com/lookup?bundleId=\(identifier)") else { 47 | DispatchQueue.main.async { 48 | completion(nil, VersionError.invalidBundleInfo) 49 | } 50 | return nil 51 | } 52 | let task = URLSession.shared.dataTask(with: url) { (data, response, error) in 53 | do { 54 | if let error = error { throw error } 55 | guard let data = data else { throw VersionError.invalidResponse } 56 | 57 | print("Data:::",data) 58 | print("response###",response!) 59 | 60 | let result = try JSONDecoder().decode(LookupResult.self, from: data) 61 | 62 | let dictionary = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves) 63 | 64 | print("dictionary",dictionary!) 65 | 66 | 67 | guard let info = result.results.first else { throw VersionError.invalidResponse } 68 | print("result:::",result) 69 | completion(info, nil) 70 | } catch { 71 | completion(nil, error) 72 | } 73 | } 74 | task.resume() 75 | 76 | print("task ******", task) 77 | return task 78 | } 79 | private func checkVersion(force: Bool) { 80 | let info = Bundle.main.infoDictionary 81 | let currentVersion = info?["CFBundleShortVersionString"] as? String 82 | _ = getAppInfo { (info, error) in 83 | 84 | let appStoreAppVersion = info?.version 85 | 86 | if let error = error { 87 | print(error) 88 | 89 | 90 | 91 | }else if appStoreAppVersion!.compare(currentVersion!, options: .numeric) == .orderedDescending { 92 | // print("needs update") 93 | // print("hiiii") 94 | DispatchQueue.main.async { 95 | let topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController! 96 | 97 | topController.showAppUpdateAlert(Version: (info?.version)!, Force: force, AppURL: (info?.trackViewUrl)!) 98 | } 99 | 100 | } 101 | } 102 | 103 | 104 | } 105 | 106 | func showUpdateWithConfirmation() { 107 | checkVersion(force : false) 108 | 109 | 110 | } 111 | 112 | func showUpdateWithForce() { 113 | checkVersion(force : true) 114 | } 115 | 116 | 117 | 118 | } 119 | 120 | extension UIViewController { 121 | 122 | 123 | fileprivate func showAppUpdateAlert( Version : String, Force: Bool, AppURL: String) { 124 | print("AppURL:::::",AppURL) 125 | 126 | let bundleName = Bundle.main.infoDictionary!["CFBundleDisplayName"] as! String; 127 | let alertMessage = "\(bundleName) Version \(Version) is available on AppStore." 128 | let alertTitle = "New Version" 129 | 130 | 131 | let alertController = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert) 132 | 133 | 134 | if !Force { 135 | let notNowButton = UIAlertAction(title: "Not Now", style: .default) { (action:UIAlertAction) in 136 | print("Don't Call API"); 137 | 138 | 139 | } 140 | alertController.addAction(notNowButton) 141 | } 142 | 143 | let updateButton = UIAlertAction(title: "Update", style: .default) { (action:UIAlertAction) in 144 | print("Call API"); 145 | print("No update") 146 | guard let url = URL(string: AppURL) else { 147 | return 148 | } 149 | if #available(iOS 10.0, *) { 150 | UIApplication.shared.open(url, options: [:], completionHandler: nil) 151 | } else { 152 | UIApplication.shared.openURL(url) 153 | } 154 | 155 | } 156 | 157 | alertController.addAction(updateButton) 158 | self.present(alertController, animated: true, completion: nil) 159 | } 160 | } 161 | --------------------------------------------------------------------------------