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

Objective-c (c#): calling (void) method while -init

提问人:Jeavie 提问时间:1/30/2019 最后编辑:Jeavie 更新时间:4/11/2019 访问量:300

问:

我正在尝试将 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 让我的大脑崩溃。任何帮助将不胜感激!

C# Objective-C 方法 Objective-C ++ 方法调用

评论

0赞 newacct 4/11/2019
你拼错了 “client” “clinet”

答:

0赞 pmdj 1/30/2019 #1

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

[self getConfigInfoWithConfigUrl: _configUrl];

请注意,方法名称在 .h 文件中的声明中有拼写错误。

事实上,您从任何其他方法执行此操作并没有什么区别。init…

评论

0赞 Jeavie 1/30/2019
当我在 .h 文件中将“+”更改为“-”时,我收到另一个错误(似乎是 obj-c 中缺少“out”attr 类似物的原因):使用未声明的标识符“_clinetSecret”;你是说“_clientSecret”吗?嗯,看起来很奇怪
1赞 newacct 4/11/2019 #2

您没有显示 Objective-C 方法的代码。由于 C# 方法是静态方法,因此您可能希望将 Objective-C 方法设为类方法,并使用以下声明:getConfigInfoWithConfigUrl:AndServiceUrl:AndClientName:AndClientSecret:AndDirections:GetConfigInfogetConfigInfoWithConfigUrl:AndServiceUrl:AndClientName:AndClientSecret:AndDirections:++(void) getConfigInfoWithConfigUrl: ...

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

outC# 中的参数表示参数是通过引用传递的。在 C 语言中,我们通常通过传递指向变量的指针来完成等效的事情。ref

所以它应该声明如下:

+ (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];