我正在尝试将C#代码重写为等效的Objective-C代码,并在-init方法内部使用称为void函数的方法带来麻烦。
C#代码中有两个构造函数,其中之一调用具有不同参数的void方法。我不知道如何在Objective-C中处理它(感觉像新手一样)。我很乐意接受任何建议!
C#类:
namespace Translation
{
public class Adapter
{
private readonly int dirId;
private readonly string serviceUrl;
private readonly string clientName;
private readonly string clientSecret;
private static Ticket _ticket = null;
private static object _ticketSync = new object();
public Adapter(int dirId, string configUrl)
{
this.dirId = dirId;
string[] directions;
//method i'm trying to call
GetConfigInfo(configUrl, out serviceUrl, out clientName, out clientSecret, out directions);
}
public Adapter(int dirId, string serviceUrl, string clientName, string clientSecret)
{
this.dirId = dirId;
this.serviceUrl = serviceUrl;
this.clientName = clientName;
this.clientSecret = clientSecret;
}
public static void GetConfigInfo(string configUrl,
out string serviceUrl, out string clientName, out string clientSecret, out string[] directions)
{
var configXml = new XmlDocument();
using (var client = new WebClient())
{
client.Credentials = new NetworkCredential("tests", "test");
var xml = client.DownloadString(configUrl);
configXml.LoadXml(xml);
}
serviceUrl = configXml.DocumentElement.SelectSingleNode("Url").InnerText.Trim();
clientName = configXml.DocumentElement.SelectSingleNode("Client").InnerText.Trim();
clientSecret = configXml.DocumentElement.SelectSingleNode("Secret").InnerText.Trim();
directions = configXml.DocumentElement.SelectSingleNode("Directions").InnerText.Trim().
Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
}
public static KeyValuePair<string, string>[] ParseTopicsInfo(string xml)
{
var topicsXml = new XmlDocument();
topicsXml.LoadXml(xml);
var result = topicsXml.SelectNodes("templates/template").OfType<XmlNode>().
Select(node =>
{
var topicId = node.SelectSingleNode("id").InnerText;
var topicName = node.SelectSingleNode("name").InnerText;
return new KeyValuePair<string, string>(topicId, topicName);
}).ToArray();
return result;
}
private Ticket CreateTicket(ServiceSoap serviceSoap)
{
if (_ticket == null || _ticket.UtcExpiredAt < DateTime.UtcNow.AddSeconds(30))
lock (_ticketSync)
if (_ticket == null || _ticket.UtcExpiredAt < DateTime.UtcNow.AddSeconds(30))
_ticket = serviceSoap.CreateTicket(clientName, clientSecret);
return _ticket;
}
public void Translate(IRanges inRanges, IRanges outRanges)
{
string text = inRanges.Text;
outRanges.OriginText = text;
bool showVariants = inRanges.Properties.GetValue(RangePropertyName.LONG_VARIANTS) != null;
bool translitUnknown = inRanges.Properties.GetValue(RangePropertyName.TRANSLIT_UNKNOWN) != null;
var topicId = (string)inRanges.Properties.GetValue(RangePropertyName.PROFILE);
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
outRanges.Text = soap.TranslateText(ticket.Token,
dirId.ToPrefix(), topicId, text, showVariants, translitUnknown);
}
}
public FindSamplesResult FindSamples(string topic, string text, int page, int pageSize, string contains, int flags)
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.FindSamples(ticket.Token,
dirId.ToPrefix(), topic, text, page, pageSize, contains, flags, System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName);
}
}
public KeyValuePairSOfStringInt32[] GetSampleStats(string text)
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.GetSampleStats(ticket.Token,
dirId.ToPrefix(), text);
}
}
public string GetTranslateSiteUrl(string url, string topic)
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.GetTranslateSiteUrl(ticket.Token,
dirId.ToPrefix(), topic, url, System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName);
}
}
public string GetDirections()
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.GetDirectionsFor(ticket.Token, "text");
}
}
public string DetectLanguage(string text)
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.AutoDetectLang(ticket.Token, text);
}
}
public GetEdInfoOrTranslateTextResult GetEdInfoOrTranslateText(string topic, string text)
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.GetEdInfoOrTranslateText(ticket.Token,
dirId.ToPrefix(), topic, text, System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName);
}
}
public KeyValuePair<string, string>[] GetTopics()
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return ParseTopicsInfo(soap.GetTopics(ticket.Token, System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName));
}
}
#region Not implemented
public void Initialize(string dirsPath, string k8Path, string mainClsid, int mainDirId, string mainPrefix, Data.IDictionaries dicts, object lms)
{
throw new NotImplementedException();
}
public string TranslateWord(string text, object flags)
{
throw new NotImplementedException();
}
public void Parse(IRanges inRanges, IRanges outRanges)
{
throw new NotImplementedException();
}
public void ParseToRangesMorphologizator(IRanges inRanges, IRanges outRanges)
{
throw new NotImplementedException();
}
public void ParseToRangesMorphologizatorAfterHR(IRanges inRanges, IRanges outRanges)
{
throw new NotImplementedException();
}
#endregion
[WebServiceBindingAttribute(Name = "test1", Namespace = "http://api.test.test/")]
public class ServiceSoap : SoapHttpClientProtocol
{
public new string Url
{
get
{
return base.Url;
}
set
{
base.Url = value;
base.UseDefaultCredentials = IsLocalFileSystemWebService(value);
}
}
[SoapDocumentMethodAttribute("http://api.test.test/CreateTicket")]
public Ticket CreateTicket(string ClientName, string ClientSecret)
{
var results = this.Invoke("CreateTicket", new object[]
{
ClientName,
ClientSecret
});
return (Ticket)results[0];
}
[SoapDocumentMethodAttribute("http://api.test.test/GetDirectionsFor")]
public string GetDirectionsFor(string Token, string For)
{
var results = this.Invoke("GetDirectionsFor", new object[]
{
Token,
For
});
return (string)results[0];
}
[SoapDocumentMethodAttribute("http://api.test.test/GetTopics")]
public string GetTopics(string Token, string Lang)
{
var results = this.Invoke("GetTopics", new object[]
{
Token,
Lang
});
return (string)results[0];
}
[SoapDocumentMethodAttribute("http://api.test.test/TranslateText")]
public string TranslateText(string Token, string DirCode, string TplId, string Text, bool ShowVariants, bool TranslitUnknown)
{
var results = this.Invoke("TranslateText", new object[]
{
Token,
DirCode,
TplId,
Text,
ShowVariants,
TranslitUnknown
});
return (string)results[0];
}
[SoapDocumentMethodAttribute("http://api.test.test/GetEdInfoOrTranslateText")]
public GetEdInfoOrTranslateTextResult GetEdInfoOrTranslateText(string Token, string DirCode, string TplId, string Text, string Lang)
{
var results = this.Invoke("GetEdInfoOrTranslateText", new object[]
{
Token,
DirCode,
TplId,
Text,
Lang
});
return (GetEdInfoOrTranslateTextResult)results[0];
}
[SoapDocumentMethodAttribute("http://api.test.test/AutoDetectLang")]
public string AutoDetectLang(string Token, string Text)
{
var results = this.Invoke("AutoDetectLang", new object[]
{
Token,
Text
});
return (string)results[0];
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://api.test.test/FindSamples", RequestNamespace = "http://api.test.test/", ResponseNamespace = "http://api.test.test/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public FindSamplesResult FindSamples(string Token, string DirCode, string Topic, string Text, int Page, int PageSize, string Contains, int Flags, string Lang)
{
object[] results = this.Invoke("FindSamples", new object[] {
Token,
DirCode,
Topic,
Text,
Page,
PageSize,
Contains,
Flags,
Lang});
return ((FindSamplesResult)(results[0]));
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://api.test.test/GetSampleStats", RequestNamespace = "http://api.test.test/", ResponseNamespace = "http://api.test.test/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public KeyValuePairSOfStringInt32[] GetSampleStats(string Token, string DirCode, string Text)
{
object[] results = this.Invoke("GetSampleStats", new object[] {
Token,
DirCode,
Text
});
return ((KeyValuePairSOfStringInt32[])(results[0]));
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://api.test.test/GetTranslateSiteUrl", RequestNamespace = "http://api.test.test/", ResponseNamespace = "http://api.test.test/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public string GetTranslateSiteUrl(string Token, string DirCode, string TopicId, string URL, string Lang)
{
object[] results = this.Invoke("GetTranslateSiteUrl", new object[] {
Token,
DirCode,
TopicId,
URL,
Lang
});
return (string)results[0];
}
private static bool IsLocalFileSystemWebService(string url)
{
if (string.IsNullOrEmpty(url))
return false;
var wsUri = new Uri(url);
if (wsUri.Port >= 1024 && string.Equals(wsUri.Host, "localhost", StringComparison.OrdinalIgnoreCase))
return true;
return false;
}
}
[XmlTypeAttribute(Namespace = "http://api.test.test/")]
public class Ticket
{
public string Token;
public DateTime UtcExpiredAt;
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class SampleRun
{
private int positionField;
private int lengthField;
/// <remarks/>
public int Position
{
get
{
return this.positionField;
}
set
{
this.positionField = value;
}
}
/// <remarks/>
public int Length
{
get
{
return this.lengthField;
}
set
{
this.lengthField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class Sample
{
private string corpusIdField;
private string sourceField;
private string translationField;
private SampleRun[] sourceRunsField;
private SampleRun[] translationRunsField;
/// <remarks/>
public string CorpusId
{
get
{
return this.corpusIdField;
}
set
{
this.corpusIdField = value;
}
}
/// <remarks/>
public string Source
{
get
{
return this.sourceField;
}
set
{
this.sourceField = value;
}
}
/// <remarks/>
public string Translation
{
get
{
return this.translationField;
}
set
{
this.translationField = value;
}
}
/// <remarks/>
public SampleRun[] SourceRuns
{
get
{
return this.sourceRunsField;
}
set
{
this.sourceRunsField = value;
}
}
/// <remarks/>
public SampleRun[] TranslationRuns
{
get
{
return this.translationRunsField;
}
set
{
this.translationRunsField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class KeyValuePairSOfStringInt32
{
private string keyField;
private int valueField;
/// <remarks/>
public string Key
{
get
{
return this.keyField;
}
set
{
this.keyField = value;
}
}
/// <remarks/>
public int Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
#region Samples
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class GetSampleStatsResult
{
private KeyValuePairSOfStringInt32[] translationsField;
public KeyValuePairSOfStringInt32[] Translations
{
get
{
return this.translationsField;
}
set
{
this.translationsField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class FindSamplesResult
{
private int totalsField;
private Sample[] samplesField;
private KeyValuePairSOfStringInt32[] corpusesField;
/// <remarks/>
public int Totals
{
get
{
return this.totalsField;
}
set
{
this.totalsField = value;
}
}
/// <remarks/>
public Sample[] Samples
{
get
{
return this.samplesField;
}
set
{
this.samplesField = value;
}
}
/// <remarks/>
public KeyValuePairSOfStringInt32[] Corpuses
{
get
{
return this.corpusesField;
}
set
{
this.corpusesField = value;
}
}
}
#endregion
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class GetEdInfoOrTranslateTextResult
{
public string ResultType { get; set; }
public string ResultText { get; set; }
}
}
}
Objective-c .h:
@interface Ticket : NSObject
{
NSString* token;
NSDate* dateTimeUtcExpiredAt;
}
@end
@interface SampleRun : NSObject
@property int* position;
@property int* length;
@end
@interface Sample : NSObject
@property NSString* corpusId;
@property NSString* source;
@property NSString* translation;
@property SampleRun* SourceRuns;
@property SampleRun* TranslationRuns;
@end
@interface KeyValuePairsOfStringInt32
@property int* totals;
@property Sample* samples;
@property KeyValuePairsOfStringInt32* corpuses;
@end
@interface GetEdInfoOrTranslateTextResult
@property NSString* resultType;
@property NSString* resultText;
@end
@interface Adapter : NSObject
{
Ticket* _ticket;
NSObject* _ticketSync;
}
@property int* dirId;
@property NSString* serviceUrl;
@property NSString* clientName;
@property NSString* clientSecret;
-(void)getConfigInfoWithConfigUrl: (NSString*) _configUrl AndServiceUrl: (NSString*) _servireUrl AndClientName: (NSString*) _clientName AndClientSecret: (NSString*) _clinetSecret AndDirections: (NSArray*) directions;
@end
Objective-c .mm:
@implementation Adapter
- (id) initWithDirId: (int*) _dirId AndConfigUrl: (NSString*) _configUrl;
{
self = [super init];
if (self) {
self.dirId = _dirId;
NSString* directions;
//here is calling (there are more params ofc)
// but i can't figure it out how to do it in the right way
[self getConfigInfoWithConfigUrl: _configUrl
AndServiceUrl: _servireUrl AndClientName: _clientName
AndClientSecret: _clinetSecret AndDirections: directions];
}
return self;
}
- (id) initBase:(int*) _dirId AndServiceUrl: (NSString*) _serviceUrl AndClientName: (NSString*) _clientName AndClientSecret: (NSString*) _clientSecret;
{
self = [super init];
if (self) {
self.dirId = _dirId;
self.serviceUrl = _serviceUrl;
self.clientName = _clientName;
self.clientSecret = _clientSecret;
}
return self;
}
@end
当我在.h文件中将'-(void)'更改为'+(void)'时(“ +”在c#中就像是静态的,因此我首先尝试过),我得到:
No visible @interface for 'OnlineAdapter' declares the selector
'getConfigInfoWithConfigUrl:AndServiceUrl:AndClientName:AndClientSecret:AndDirections:'
当我用'-(void)'呼叫时,出现错误:
Use of undeclared identifier '_clinetSecret';
did you mean '_clientSecret'? //etc. for other args
我想这是由于C#代码中的'out'attr而发生的,但是我不确定obj-c中是否存在类似物。
Objective-c使我的大脑崩溃。任何帮助将不胜感激!
答案 0 :(得分:1)
您没有显示您的Objective-C方法getConfigInfoWithConfigUrl:AndServiceUrl:AndClientName:AndClientSecret:AndDirections:
的代码。由于您的C#方法GetConfigInfo
是静态方法,因此您可能希望将Objective-C方法getConfigInfoWithConfigUrl:AndServiceUrl:AndClientName:AndClientSecret:AndDirections:
设为类方法,并用+
声明:+(void) getConfigInfoWithConfigUrl: ...
将需要在类对象上而不是在普通实例上调用类方法:[Adapter getConfigInfoWithConfigUrl: ...]
out
和ref
参数表示该参数是通过引用传递的。在C语言中,我们通常通过将指针传递给变量来完成等效操作。
因此应声明为以下内容:
+ (void)getConfigInfoWithConfigUrl:(NSString *)_configUrl
AndServiceUrl:(NSString **)_servireUrl
AndClientName:(NSString **)_clientName
AndClientSecret:(NSString **)_clientSecret
AndDirections:(NSArray**)directions;
在方法内部,它将分配给以下变量:
*serviceUrl = ...
*clientName = ...
*clientSecret = ...
*directions = ...
您这样称呼它:
[Adapter getConfigInfoWithConfigUrl:_configUrl
AndServiceUrl:&_servireUrl
AndClientName:&_clientName
AndClientSecret:&_clientSecret
AndDirections:&directions];
答案 1 :(得分:0)
self
仅隐式用于访问实例变量(ivars),而不用于方法调用。因此,您始终需要使用以下语法:
[self getConfigInfoWithConfigUrl: _configUrl];
请注意,方法名称在.h文件的声明中有错字。
您通过init…
与任何其他方法进行此操作的事实没有区别。