Objective-c(c#):在-init时调用(void)方法

Objective-c(c#):在-init时调用(void)方法,c#,objective-c,methods,objective-c++,method-call,C#,Objective C,Methods,Objective C++,Method Call,我试图将C#代码重写为等效的objective-C代码,并在-init方法内部调用void函数时遇到一些麻烦 C#代码中有两个构造函数,其中一个使用不同的参数调用void方法。我不知道如何在objective-c中处理它(感觉像个新手)。我很乐意接受任何建议 C#class: namespace Translation { public class Adapter { private readonly int dirId; private read

我试图将C#代码重写为等效的objective-C代码,并在-init方法内部调用void函数时遇到一些麻烦

C#代码中有两个构造函数,其中一个使用不同的参数调用void方法。我不知道如何在objective-c中处理它(感觉像个新手)。我很乐意接受任何建议

C#class

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.mm:

@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
@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#中的static,所以我先尝试过),我得到:

当我使用“-(void)”调用时,会出现错误:

    Use of undeclared identifier '_clinetSecret';
did you mean '_clientSecret'? //etc. for other args
我猜这是因为C#code中的'out'attr,但我不确定obj-C中是否有类似的东西


Objective-c毁了我的大脑。任何帮助都将不胜感激

Objective-C中的self仅隐式用于访问实例变量(IVAR),而不用于方法调用。因此,您始终需要使用以下语法:

[self getConfigInfoWithConfigUrl: _configUrl];
请注意,方法名在.h文件中的声明中有一个输入错误


与任何其他方法相比,您从
init…
执行此操作的事实没有任何区别。

您没有显示Objective-C方法的代码
getConfigInfoWithConfigUrl:AndServiceUrl:AndClientName:AndClientSecret:AndDirections:
。由于您的C#方法
GetConfigInfo
是一个静态方法,因此您可能希望将Objective-C方法
getConfigInfoWithConfigUrl:AndServiceUrl:AndClientName:AndClientSecret:AndDirections:
作为一个类方法,用
+
声明:
+(void)getConfigInfoWithConfigUrl:…

类方法需要在类对象上调用,而不是在普通实例上调用:
[Adapter getConfigInfoWithConfigUrl:…]

C#中的
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];
在方法内部,它将分配给如下变量:

+ (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];
你可以这样称呼它:

+ (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];
当我将.h文件中的“+”更改为“-”时,我得到另一个错误(似乎是obj-c中缺少“out”attr模拟的原因):使用未声明的标识符“_clinetSecret”;你是说“客户秘密”吗?看起来很奇怪你把“客户”和“客户”拼错了