iOS:pipe理REST端点的简单方法

我们基于REST的应用程序可用于在多个内部环境中进行testing,每个环境都有不同的REST端点。 有没有一种简单的方法来设置iOS(Swift 3)应用程序中的环境级别configuration? 我已经看到了一些方法,但他们似乎都相当参与。

我发现为您的项目创build不同的Scheme和Configuration效果最好。 我的设置如下:

我通常有3种不同的scheme, MyApp-devMyApp-stagingMyApp

每个我创buildUser-Defined-Attributescheme都有不同的string附加到我的Bundle Display Name 。 所以它可以同时出现在我的iOS设备上,如MyApp-dMyApp-sMyApp 。 每个也有它自己的Bundle ID然后我为他们每个创build自定义标志。

所以在我的Routes.swift文件中,我在顶端有这样的东西:

 #if PRODUCTION static let hostName = "http://production.com/api/v1/" #elseif STAGING static let hostName = "http://staging.com/api/v1/" #else static let hostName = "http://development.com/api/v1/" #endif 

如何更新不同的主机名有很多种方法。 但最终创build不同的scheme和configuration总是第一步。

以下是可帮助您开始的几个链接:

https://medium.com/@danielgalasko/change-your-api-endpoint-environment-using-xcode-configurations-in-swift-c1ad2722200e#.o6nhic3pf

http://limlab.io/swift/2016/02/22/xcode-working-with-multiple-environments.html

正如Zac Kwan所build议的那样,您可以使用不同的scheme来实现这一点,但是您也不一定要创build不同的configuration。 每个scheme可以指定独特的环境variables。 然后,从Swift访问它们:

 let prodURL = "http://api.com" let baseURL = ProcessInfo.processInfo.environment["BASE_URL"] ?? prodURL 

当我们有多个终点时,这是我做事的方法。 我曾经做过这样的ConfigurationManager

Swift 3.0代码

 import Foundation import UIKit let kEnvironmentsPlist:NSString? = "Environments" let kConfigurationKey:NSString? = "ActiveConfiguration" let kAPIEndpointKey:NSString? = "APIEndPoint" let kLoggingEnabledKey:NSString? = "LoggingEnabled" let kAnalyticsTrackingEnabled:NSString? = "AnalyticsTrackingEnabled" class ConfigurationManager:NSObject { var environment : NSDictionary? //Singleton Method static let sharedInstance: ConfigurationManager = { let instance = ConfigurationManager() // setup code return instance }() override init() { super.init() initialize() } // Private method func initialize () { var environments: NSDictionary? if let envsPlistPath = Bundle.main.path(forResource: "Environments", ofType: "plist") { environments = NSDictionary(contentsOfFile: envsPlistPath) } self.environment = environments!.object(forKey: currentConfiguration()) as? NSDictionary if self.environment == nil { assertionFailure(NSLocalizedString("Unable to load application configuration", comment: "Unable to load application configuration")) } } // CurrentConfiguration func currentConfiguration () -> String { let configuration = Bundle.main.infoDictionary?[kConfigurationKey! as String] as? String return configuration! } // APIEndpoint func APIEndpoint () -> String { let configuration = self.environment![kAPIEndpointKey!] return (configuration)! as! String } // isLoggingEnabled func isLoggingEnabled () -> Bool { let configuration = self.environment![kLoggingEnabledKey!] return (configuration)! as! Bool } // isAnalyticsTrackingEnabled func isAnalyticsTrackingEnabled () -> String { let configuration = self.environment![kAnalyticsTrackingEnabled!] return (configuration)! as! String } func applicationName()->String{ let bundleDict = Bundle.main.infoDictionary! as NSDictionary return bundleDict.object(forKey: "CFBundleName") as! String } } 

项目 – > 信息中根据需要添加一些新的configuration。

在这里输入图像说明

我添加了StagingQA作为额外的端点。通常我使用Staging作为Releaseconfiguration和QA作为Debug。 所以它看起来像:

在这里输入图像说明

现在转到目标 – > 生成设置,并添加一个用户定义的设置

在这里输入图像说明

给定用户的名字,如ACTIVE_CONFIGURATION

在这里输入图像说明

info.plist添加一个名为ActiveConfiguration的密钥,其variables名称为$(ACTIVE_CONFIGURATION)用户定义的设置中给出的一样,开头为$ 。 我们将Key的名称命名为ActiveConfiguration因为我们在ConfigurationManager.swift类中为kConfigurationKey使用了相同的名称。

 let kConfigurationKey:NSString? = "ActiveConfiguration" 

您可以按照您的命名约定进行定义。

它会看起来像:

在这里输入图像说明

现在在ConfigurationManager类中,我正在获取Environments.plist文件的path。

我将只创build一个Environments.plist文件,如下所示:

在这里输入图像说明

这个文件的实际描述来源是

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Development</key> <dict> <key>APIEndPoint</key> <string>https://dev</string> <key>LoggingEnabled</key> <true/> <key>AnalyticsTrackingEnabled</key> <true/> <key>Flurry</key> <dict> <key>FlurryApplicationID</key> <string></string> <key>FlurryApplicationSecret</key> <string></string> </dict> <key>Facebook</key> <dict> <key>FacebookAppID</key> <string></string> <key>FacebookAppSecret</key> <string></string> </dict> </dict> <key>QA</key> <dict> <key>APIEndPoint</key> <string>https://qa</string> <key>LoggingEnabled</key> <true/> <key>AnalyticsTrackingEnabled</key> <true/> <key>Flurry</key> <dict> <key>FlurryApplicationID</key> <string></string> <key>FlurryApplicationSecret</key> <string></string> </dict> <key>Facebook</key> <dict> <key>FacebookAppID</key> <string></string> <key>FacebookAppSecret</key> <string></string> </dict> </dict> <key>Staging</key> <dict> <key>APIEndPoint</key> <string>https://staging</string> <key>LoggingEnabled</key> <false/> <key>AnalyticsTrackingEnabled</key> <true/> <key>Flurry</key> <dict> <key>FlurryApplicationID</key> <string></string> <key>FlurryApplicationSecret</key> <string></string> </dict> <key>Facebook</key> <dict> <key>FacebookAppID</key> <string>840474532726958</string> <key>FacebookAppSecret</key> <string></string> </dict> </dict> <key>Production</key> <dict> <key>APIEndPoint</key> <string>https://production</string> <key>LoggingEnabled</key> <true/> <key>AnalyticsTrackingEnabled</key> <true/> <key>Flurry</key> <dict> <key>FlurryApplicationID</key> <string></string> <key>FlurryApplicationSecret</key> <string></string> </dict> <key>Facebook</key> <dict> <key>FacebookAppID</key> <string></string> <key>FacebookAppSecret</key> <string></string> </dict> </dict> </dict> </plist> 

我们现在好走了。 现在你只需要打电话

 ConfigurationManager.sharedInstance.APIEndpoint() 

为您的各自的终点。

现在你只需要从Edit Schemes中改变scheme,你就完成了,并且在info中改变了Build Configuration

在这里输入图像说明

在这里输入图像说明

这不仅可以pipe理API端点 ,还可以pipe理其他function,例如是否针对不同端点启用分析或跟踪Facebook的相应terminal或Facebook的不同ID。

我结束了使用https://github.com/theappbusiness/ConfigGenerator

自动生成configuration文件代码的命令行工具,用于Xcode项目。 Configen工具用于从属性列表中自动生成configuration代码。 它旨在创build您的应用使用的外部URL或API密钥所需的configurationtypes。 目前支持Swift和Objective-C代码生成。