我正在尝试测试一段代码,我检查一下帐户是否已经创建了一个密钥并将其存储在钥匙串中.如果不是,则调用启动oauth进程的方法.
我的第一个想法是覆盖我想要调用的方法,如果用户没有秘密密钥.但是我使用的是结构,因此无法继承和覆盖该方法.
如果我使用的是课程,我会这样:
func testInitiateOauthCalledIfSecretKeyNotFound() {
class MockKeychainAccess: KeychainAccess {
var initiateAuthorizationWasCalled: Bool = false
override initiateAuthorization() {
initiateAuthorizationWasCalled = true
}
let keychainAccess = MockKeychainAccess()
keychainAccess.authorizeWithGoogle()
XCTAssertTrue(initiateAuthorizationWasCalled)
}
Run Code Online (Sandbox Code Playgroud)
我没有测试过这段代码所以不确定它是否编译.但从逻辑上讲,它似乎可以处理我追求的情况.如果在authorizeWithGoogle我们调用的方法中,initiateAuthorization()我会知道已经发生了.但是,当他们使用结构时,我们无法从结构中继承,因此无法执行此操作.
请注意:我是TDD的新手,所以也许我正在以错误的方式思考这个问题.其他建议是受欢迎的.但是我不想只是为了编写测试而从结构转换为类.我正在使用结构,因为我试图更加迅速.
有没有人知道我可以测试是否在结构中调用函数的方法?
==========
编辑:
为了回答dassm回答,我添加了一个我想要实现的一般方法的例子:
override func viewDidLoad() {
setupView()
let api = DataApi()
getData(api)
}
func setupView() {
tableView.dataSource = tableViewDataSource
}
func getData(api: DataApi) {
api.getApplicationData( { (objects) in
if let applications = objects as? [Application] {
self.tableViewDataSource.setApplicationItems(applications)
self.tableView.reloadData()
}
else {
// …Run Code Online (Sandbox Code Playgroud) 我目前正在使用Moya来发出我的网络请求.我已经从其中一个示例项目实现了以下内容@ https://github.com/DroidsOnRoids/RxSwiftExamples#tutorials
下面我设置了restaurantSearch,这样当有人输入文本时,它会发出新的请求.
var restaurantSearch: Observable<(String)> {
return searchBar
.rx_text
.throttle(0.5, scheduler: MainScheduler.instance)
.distinctUntilChanged()
}
Run Code Online (Sandbox Code Playgroud)
我有一个方法返回类型[餐厅]的观察
func restaurants() -> Observable<[Restaurant]> {
return restaurantSearch
.observeOn(MainScheduler.instance)
.flatMapLatest { postcode -> Observable<[Restaurant]?> in
return self.getRestaurants(postcode, cuisine: "", restaurantName: "")
}.replaceNilWith([])
}
internal func getRestaurants(postcode: String, cuisine: String, restaurantName: String) -> Observable<[Restaurant]?> {
return self.justEatProvider
.request(.Restaurant(postcode, cuisine, restaurantName))
.debug()
.mapArrayOptional(Restaurant.self, keyPath: "Restaurants")
}
Run Code Online (Sandbox Code Playgroud)
我正在调用此方法并将其绑定到tableView,如下所示:
func setupRx() {
api = JustEatApi(provider: provider, restaurantSearch: restaurantSearch)
api
.restaurants()
.bindTo(tableView.rx_itemsWithCellIdentifier("RestaurantTableViewCell", cellType: RestaurantTableViewCell.self)) { (row, element, cell) in
cell.restaurant …Run Code Online (Sandbox Code Playgroud) 我已经创建了一个UIView的自定义子类以及一个xib文件,并在自定义类中声明了IBOutlets和IBActions.
@interface ContactUsView : UIView
@property (nonatomic, weak) IBOutlet UIButton *displayCloseButton;
- (IBAction)callButtonPressed:(id)sender;
- (IBAction)emailButtonPressed:(id)sender;
- (IBAction)displayCloseButtonPressed:(id)sender;
@end
Run Code Online (Sandbox Code Playgroud)
在xib文件中,我拖入UIView来表示我的自定义视图.我已经设定:
然后我添加了各种按钮,这些按钮与上述3种方法相连.
在ContactUsView.m内部,我有以下内容:
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
NSArray* array = [[NSBundle mainBundle] loadNibNamed:@"ContactUsView" owner:self options:nil];
for (id object in array) {
if ([object isKindOfClass:[ContactUsView class]])
self = (ContactUsView *)object;
}
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
当我创建此视图时,我执行以下操作:
- (void)viewWillAppear:(BOOL)animated
{
ContactUsView *contactUs = [[ContactUsView alloc] initWithFrame:CGRectZero];
CGPoint origin = self.view.frame.origin;
CGSize size = self.view.frame.size;
[contactUs setFrame:CGRectMake(origin.x,
CGRectGetMaxY(self.view.frame) …Run Code Online (Sandbox Code Playgroud) 我目前正在尝试使用OAuth2授权我的用户.我目前正在使用以下库:https://github.com/p2/OAuth2
let oauth2 = OAuth2CodeGrant(settings: [
"client_id": "my-id",
"authorize_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://www.googleapis.com/oauth2/v3/token",
"scope": "profile", // depends on the API you use
"redirect_uris": ["com.TestAuthorizeApp:/oauth2Callback"],
])
//let oauth2 = OAuth2CodeGrant(settings: settings)
oauth2.onAuthorize = { parameters in
print("Did authorize with parameters: \(parameters)")
}
oauth2.onFailure = { error in // `error` is nil on cancel
if let error = error {
print("Authorization went wrong: \(error)")
}
}
oauth2.authConfig.authorizeEmbedded = false
oauth2.authorize()
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它在浏览器中加载谷歌,我能够登录.然后它询问我在范围内声明的权限,并且工作正常.我点击确定打开,它将我重定向回我的应用程序.
但是,当我再次运行此代码时,我希望访问令牌已存储在密钥链中.然而,这似乎不起作用.
我查看了源代码并找到了以下检查:tryToObtainAccessTokenIfNeeded总是返回false.这意味着我再次获取页面,我需要单击"允许".
我想知道是否有人可以帮我弄清楚为什么它不能保存钥匙串中的任何东西.这是否意味着用户并未真正进行身份验证?
谢谢.
===
编辑
oauth2.verbose …
今天我尝试在Xcode中使用容器视图,当我在Library菜单底部的栏中搜索时,我找不到它.我也搜索了整个列表,但找不到它.
有谁知道可能会发生什么.我正在使用Xcode 6.4.
任何建议将不胜感激.
我一直在寻找扫描1d条形码的解决方案,并提出了以下答案:ios应用程序中的QR码扫描
我正在为iOS 8开发,对上述问题的第二个答案解决了我们不再需要使用第三方库这一事实.这似乎相对简单.
有些应用程序可以扫描条形码,然后您可以在设备上查看条形码.我假设他们正在从扫描的条形码创建一个UIImage.但是我不确定如何在我的应用程序中实现相同的功能.
有没有人知道处理这种行为的代码示例或库?
我正在实现一个UITableview,我想拥有一个包含每个部分标题的数组.
let titleOne = "Hello World"
let titleTwo = "What's next"
let titleThree = "Extras"
let headerTitles = [titleOne, titleTwo, titleThree]
Run Code Online (Sandbox Code Playgroud)
这样我就可以通过以下方法访问数组:
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return headerTitles[section]
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试将数组声明为类变量并添加静态字符串时,我收到以下错误:
'name.Type'没有名为'titleOne'的成员
我已阅读以下内容并理解为什么上述情况不可能:'Class.Type'没有名为'variable'的成员错误只是缺少类变量支持?
有没有办法优雅地使用常量字符串创建数组而不使用数组中的字符串文字,也没有在方法中执行它?我想也许是一个结构?或者这有点矫枉过正?
谢谢.
最初,我在检查是否已将数据保存到钥匙串中时遇到了问题。我找到了这篇文章并遵循了 BhavinBhadani 的建议:
每当您检查 if ([GIDSignIn sharedInstance].hasAuthInKeychain) 时,在此之前添加您的登录范围..
https://github.com/googlesamples/google-services/issues/27
这解决了我GIDSignIn.sharedInstance().hasAuthInKeychain()在用户之前成功登录然后杀死应用程序并重新运行后返回 true 的第一个问题。
但是现在我正在做以下事情:
let signIn = GIDSignIn.sharedInstance()
signIn.scopes = [Constants.GOOGLE_CLIENT_SCOPE, Constants.GOOGLE_OIDC_SCOPE]
if GIDSignIn.sharedInstance().hasAuthInKeychain() {
print("We have saved in keychain")
if let u = GIDSignIn.sharedInstance().currentUser {
getData(dataApi)
}
else {
// THIS CODE IS BEING SUCCESSFULLY HIT
GIDSignIn.sharedInstance().signInSilently()
getApplicationData(dataApi)
}
}
Run Code Online (Sandbox Code Playgroud)
然而,即使在做GIDSignIn.sharedInstance().signInSilently()了之后:GIDSignIn.sharedInstance().currentUser是零。
有没有人成功用于signInSilently()再次填充 currentUser 数据?
我目前在第二个分支机构上工作NC12-changePassword。
对master分支进行了更改,该分支处理字符串的解密。我需要这些新更改才能在我的分支上实现新功能,因此我合并了这些更改。
我做了一个git pull,没有冲突。当我运行时,git log它显示合并提交。另外,当我运行时,git merge master它告诉我一切都是最新的。
但是我的代码不起作用,当我运行git时,diff NC12-changePassword master它列出了in master中没有的内容NC12-changePassword。这对我来说没有意义,因为我已经合并了更改,因此master中的所有内容都应包含在其中NC12-changePassword。
我的理解是我的分支应该可以正常运行master并且代码应该可以正常工作。还是我想念一些东西:-\。
我目前正在尝试实现一种计算字符串中字符和数字数量的方法。但是,如果我使用包含“\”字符的字符串,我会得到奇怪的结果。我猜这是因为反斜杠字符是转义字符。
方法如下:
import Data.Char
countLettersAndDigits :: String -> Int
countLettersAndDigits [] = 0
countLettersAndDigits (x:xs) = if isDigit x == True || isLetter x == True
then 1 + countLettersAndDigits xs
else countLettersAndDigits xs
Run Code Online (Sandbox Code Playgroud)
这是一组输入及其各自的结果:
"1234fd" -> 6(不包含 '\')
“1234f\d” -> 字符“d”处字符串/字符文字中的词法错误
“1234\fd”-> 5
“123\4fd”-> 5
“12\34fd”-> 4
“1\234fd”-> 4
“\1234fd”-> 3
我觉得很奇怪,例如,“1234\fd”和“123\4fd”的结果都是 5。
有什么帮助解释为什么会出现这种情况以及如何解决这个问题吗?会很好!
干杯。
编辑
我忘了提及,上面使用的字符串只是我正在使用的一个示例。导致问题的实际字符串是由快速检查生成的。该字符串是“\178”。因此,当它们只有一个反斜杠并且正在为我生成字符串时,我需要一种能够在代码中处理这种情况的方法。干杯。