এনএসএলগের জন্য একটি সুইফ্ট বিকল্প আছে (@ "% s", __PRETTY_FUNCTION__)


88

উদ্দেশ্য সিতে আপনি যে পদ্ধতিটি ব্যবহার করে ডাকা হচ্ছে সে পদ্ধতিটি লগ করতে পারেন:

NSLog(@"%s", __PRETTY_FUNCTION__)

সাধারণত এটি লগিং ম্যাক্রো থেকে ব্যবহৃত হয়।

যদিও সুইফ্ট ম্যাক্রোর সমর্থন করে না (আমি মনে করি) আমি এখনও একটি জেনেরিক লগ স্টেটমেন্ট ব্যবহার করতে চাই যার মধ্যে ডাকা ফাংশনটির নাম অন্তর্ভুক্ত রয়েছে। সুইফটে কি তা সম্ভব?

আপডেট: আমি এখন লগিংয়ের জন্য এই গ্লোবাল ফাংশনটি ব্যবহার করি যা এখানে পাওয়া যাবে: https://github.com/evermeer/Stuff#print এবং যা আপনি ব্যবহার করে ইনস্টল করতে পারেন:

pod 'Stuff/Print'

কোডটি এখানে:

public class Stuff {

    public enum logLevel: Int {
        case info = 1
        case debug = 2
        case warn = 3
        case error = 4
        case fatal = 5
        case none = 6

        public func description() -> String {
            switch self {
            case .info:
                return "❓"
            case .debug:
                return "✳️"
            case .warn:
                return "⚠️"
            case .error:
                return "🚫"
            case .fatal:
                return "🆘"
            case .none:
                return ""
            }
        }
    }

    public static var minimumLogLevel: logLevel = .info

    public static func print<T>(_ object: T, _ level: logLevel = .debug, filename: String = #file, line: Int = #line, funcname: String = #function) {
        if level.rawValue >= Stuff.minimumLogLevel.rawValue {
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "MM/dd/yyyy HH:mm:ss:SSS"
            let process = ProcessInfo.processInfo
            let threadId = "?"
            let file = URL(string: filename)?.lastPathComponent ?? ""
            Swift.print("\n\(level.description()) .\(level) ⏱ \(dateFormatter.string(from: Foundation.Date())) 📱 \(process.processName) [\(process.processIdentifier):\(threadId)] 📂 \(file)(\(line)) ⚙️ \(funcname) ➡️\r\t\(object)")
        }
    }
}

যা আপনি এটির মতো ব্যবহার করতে পারেন:

Stuff.print("Just as the standard print but now with detailed information")
Stuff.print("Now it's a warning", .warn)
Stuff.print("Or even an error", .error)

Stuff.minimumLogLevel = .error
Stuff.print("Now you won't see normal log output")
Stuff.print("Only errors are shown", .error)

Stuff.minimumLogLevel = .none
Stuff.print("Or if it's disabled you won't see any log", .error)    

যার ফলশ্রুতিতে হবে:

✳️ .debug ⏱ 02/13/2017 09:52:51:852 📱 xctest [18960:?] 📂 PrintStuffTests.swift(15) ⚙️ testExample() ➡️
    Just as the standard print but now with detailed information

⚠️ .warn ⏱ 02/13/2017 09:52:51:855 📱 xctest [18960:?] 📂 PrintStuffTests.swift(16) ⚙️ testExample() ➡️
    Now it's a warning

🚫 .error ⏱ 02/13/2017 09:52:51:855 📱 xctest [18960:?] 📂 PrintStuffTests.swift(17) ⚙️ testExample() ➡️
    Or even an error

🚫 .error ⏱ 02/13/2017 09:52:51:855 📱 xctest [18960:?] 📂 PrintStuffTests.swift(21) ⚙️ testExample() ➡️
    Only errors are shown

4
আমি ব্যবহার করিNSLog("Running %@ : %@",NSStringFromClass(self.dynamicType),__FUNCTION__)
ম্যাগস্টার


4
আমি মনে করি আপনার লগিং শৈলীটি "সুন্দর ফাংশন" এর সংজ্ঞা হওয়া উচিত। ভাগ করে নেওয়ার জন্য ধন্যবাদ.
হুয়াথাম

উত্তর:


101

সুইফট হয়েছে #file, #function, #line এবং #column। থেকে সুইফট প্রোগ্রামিং ভাষা :

#file - স্ট্রিং - এটি প্রদর্শিত ফাইলের নাম।

#line - ইনট - যে লাইনের নম্বর এটি প্রদর্শিত হবে।

#column - Int - কলাম নম্বর এটিতে এটি শুরু হয়।

#function - স্ট্রিং - ঘোষণার নাম যেখানে এটি প্রদর্শিত হবে।


11
অবশ্যই নিশ্চিত - সি থেকে যারা এগিয়ে আছে তারা কিন্তু এই সম্পর্কে প্রশ্নের উত্তর দেয় __PRETTY_FUNCTION__না যা দেওয়া বিকল্পগুলি থেকে সহজে তৈরি হয় না isn't (সেখানে কি আছে __CLASS__? যদি তা সাহায্য করে তবে))
অলি

10
সুইফট 2.2 ইন #function, #file এবং অন্যদের ব্যবহার করা উচিত যেমন এখানে দেখানো: stackoverflow.com/a/35991392/1151916
রামিস

70

সুইফট ২.২ থেকে শুরু করে আমাদের ব্যবহার করা উচিত:

  • # ফাইল (স্ট্রিং) এটি প্রদর্শিত ফাইলের নাম The
  • # লাইন (ইন্ট) লাইন নম্বর এটিতে প্রদর্শিত হয় number
  • # কলাম (ইন্ট) কলাম নম্বর এটিতে এটি শুরু হয়।
  • # ফাংশন (স্ট্রিং) এটি ঘোষণার নাম যেখানে এটি প্রদর্শিত হবে।

থেকে সুইফট প্রোগ্রামিং ল্যাঙ্গুয়েজ (সুইফট 3.1) পৃষ্ঠা 894 এ।

func specialLiterals() {
    print("#file literal from file: \(#file)")
    print("#function literal from function: \(#function)")
    print("#line: \(#line) -> #column: \(#column)")
}
// Output:
// #file literal from file: My.playground
// #function literal from function: specialLiterals()
// #line: 10 -> #column: 42

4
এটি বর্তমানে সঠিক উত্তর হিসাবে চিহ্নিত করা উচিত।
ড্যানি ব্রাভো

18

সুইফট 4
এখানে আমার পদ্ধতির বিষয়:

func pretty_function(_ file: String = #file, function: String = #function, line: Int = #line) {

    let fileString: NSString = NSString(string: file)

    if Thread.isMainThread {
        print("file:\(fileString.lastPathComponent) function:\(function) line:\(line) [M]")
    } else {
        print("file:\(fileString.lastPathComponent) function:\(function) line:\(line) [T]")
    }
}

এটি একটি বৈশ্বিক ফাংশন করুন এবং কেবল কল করুন

pretty_function()

বোনাস: আপনি দেখতে পাবেন যে থ্রেডটি কার্যকর হয়েছে, [টি] একটি পটভূমি থ্রেডের জন্য এবং [এম] মূল থ্রেডের জন্য।


স্ট্রিং থেকে এনএসএসস্ট্রিং-এ ফাইলের ঘোষণাপত্র পরিবর্তন করা দরকার। সর্বশেষপ্যাথকম্পোনটি স্ট্রিংয়ে উপলভ্য নয়।
primulaveris

4
চরম দোস্ত. সুইফট> ২.১ এর জন্য ক্ষুদ্র পরিবর্তন: "মুদ্রণ" এর নাম পরিবর্তন করে "মুদ্রণ" করা হয়েছে। মুদ্রণ ("ফাইল: (file.debugDescript) ফাংশন: (ফাংশন) লাইন: (লাইন)")
জন দো

দুর্দান্ত, ভাল যে এটি কাজ করে। এতে কোনওভাবে শ্রেণি / অবজেক্টটি পাস করতে সক্ষম হতে পেরেও দুর্দান্ত লাগবে (একটি বিকল্প হ'ল সুস্পষ্ট স্ব-যুক্তি ব্যবহার করা)। ধন্যবাদ
তিব্বতের সমুদ্র উপকূল

আপনার পদ্ধতির সাথে সমস্যা: - এই ফাংশনটি থ্রেড-নিরাপদ নয়। যদি আপনি এটি একবারে বিভিন্ন থ্রেড থেকে কল করেন তবে কিছু খারাপ বিস্ময়ের জন্য প্রস্তুত থাকুন - বিশ্বব্যাপী ফাংশনগুলি ব্যবহার করা খারাপ অভ্যাস
কারোলি নিস্তজোর

9

এক্সকোড বিটা 6 অনুসারে, আপনি reflect(self).summaryক্লাসের নাম এবং __FUNCTION__ফাংশনটির নাম পেতে ব্যবহার করতে পারেন তবে জিনিসগুলি এখনই কিছুটা ম্যাঙ্গাল হয়েছে। আশা করি, তারা আরও ভাল সমাধান নিয়ে আসবে। আমরা বিটা থেকে বের না হওয়া অবধি # ডিফাইন ব্যবহার করা সার্থক হতে পারে।

এই কোড:

NSLog("[%@ %@]", reflect(self).summary, __FUNCTION__)

এর মতো ফলাফল দেয়:

2014-08-24 08:46:26.606 SwiftLessons[427:16981938] [C12SwiftLessons24HelloWorldViewController (has 2 children) goodbyeActiongoodbyeAction]

সম্পাদনা: এটি আরও কোড, তবে আমার যা প্রয়োজন তা আরও কাছে পেয়ে গেলেন, যা আমার মনে হয় আপনি যা চেয়েছিলেন তা।

func intFromString(str: String) -> Int
{
    var result = 0;
    for chr in str.unicodeScalars
    {
        if (chr.isDigit())
        {
            let value = chr - "0";
            result *= 10;
            result += value;
        }
        else
        {
            break;
        }
    }

    return result;
}


@IBAction func flowAction(AnyObject)
{
    let cname = _stdlib_getTypeName(self)
    var parse = cname.substringFromIndex(1)                                 // strip off the "C"
    var count = self.intFromString(parse)
    var countStr = String(format: "%d", count)                              // get the number at the beginning
    parse = parse.substringFromIndex(countStr.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
    let appName = parse.substringToIndex(count)                             // pull the app name

    parse = parse.substringFromIndex(count);                                // now get the class name
    count = self.intFromString(parse)
    countStr = String(format: "%d", count)
    parse = parse.substringFromIndex(countStr.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
    let className = parse.substringToIndex(count)
    NSLog("app: %@ class: %@ func: %@", appName, className, __FUNCTION__)
}

এটি এর মতো আউটপুট দেয়:

2014-08-24 09:52:12.159 SwiftLessons[1397:17145716] app: SwiftLessons class: ViewController func: flowAction

8

আমি একটি গ্লোবাল লগ ফাংশন সংজ্ঞায়িত করতে পছন্দ করি:

[দ্রুত ৩.১]

func ZYLog(_ object: Any?, filename: String = #file, line: Int = #line, funcname: String = #function) {
    #if DEBUG
    print("****\(Date()) \(filename)(\(line)) \(funcname):\r\(object ?? "nil")\n")
    #endif
}

[সুইফট ৩.০]

func ZYLog<T>(_ object: T?, filename: String = #file, line: Int = #line, funcname: String = #function) {
    #if DEBUG
    print("****\(Date()) \(filename)(\(line)) \(funcname):\r\(object)\n")
    #endif
}

[সুইফট ২.০]

func ZYLog<T>(object: T, filename: String = __FILE__, line: Int = __LINE__, funcname: String = __FUNCTION__) {
    println("****\(filename.lastPathComponent)(\(line)) \(funcname):\r\(object)\n")
}

আউটপুট যেমন কিছু:

****ZYHttpSessionManager.swift(78) POST(_:parameters:success:failure:):
[POST] user/login, {
    "auth_key" = xxx;
    "auth_type" = 0;
    pwd = xxx;
    user = "xxx";
}

****PointViewController.swift(162) loadData():
review/list [limit: 30, skip: 0]

****ZYHttpSessionManager.swift(66) GET(_:parameters:success:failure:):
[GET] review/list, {
    "auth_key" = xxx;
    uuid = "xxx";
}

আপনার এখানে আসলে জেনেরিক ফাংশন দরকার নেই, কারণ objectপ্যারামিটার Anyপরিবর্তে ঘোষণা করা যেতে পারে T
ওয়েলডিভার

5

এখানে একটি আপডেট সুইফট 2 উত্তর দেওয়া হয়েছে।

func LogW(msg:String, function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__){
    print("[WARNING]\(makeTag(function, file: file, line: line)) : \(msg)")
}

private func makeTag(function: String, file: String, line: Int) -> String{
    let url = NSURL(fileURLWithPath: file)
    let className:String! = url.lastPathComponent == nil ? file: url.lastPathComponent!
    return "\(className) \(function)[\(line)]"
}

ব্যবহারের উদাহরণ:

LogW("Socket connection error: \(error)")

4
এটি দুর্দান্ত। তবে আবার .. লগডাব্লু প্রিন্টের মতো হুবহু ব্যবহার করা যাবে না () প্যারামিটার সহ, কমা দ্বারা পৃথক) ..
গুঁটিস ট্রুলেন্ডস

"লগডাব্লু প্রিন্টের মতো হুবহু ব্যবহার করা যাবে না (প্যারামিটার সহ, কমা দ্বারা পৃথক করা" আমি এই সমর্থনটি যুক্ত করার কথা ভাবছিলাম কিন্তু আমি পেয়েছি আমার এটির দরকার নেই। "লগডাব্লু (" সকেট সংযোগ ত্রুটি: (ত্রুটি)) অন্যান্য তথ্য : (otherInfo) ")"
ড্যানিয়েল রায়ান

4
সত্য। আমি চারপাশে টিনক করেছিলাম এবং কেবলমাত্র অন্যান্য সমাধানই আমি পেয়েছি - বিবৃতিটি ধরে রাখতে অতিরিক্ত () ব্যবহার করে, যতটা সম্ভব মুদ্রণের অনুরূপ তৈরি করা ()। আপনার এই উত্তরটি তৈরি করতে আপনার উত্তরটি ব্যবহার করেছেন github.com/GuntisTreulands/CororLogger- যেভাবেই হোক সুইফট , অনেক ধন্যবাদ! :)
গুঁটিস ট্রুলেন্ডস

খুব দরকারী! সুইফট ২.২ হিসাবে,__FUNCTION__ becomes #function, __FILE__ becomes #file, and __LINE__ becomes #line.
কার্ল স্মিথ

নতুন মূল্যবোধ নিয়ে আমাদের সমস্যা ছিল। আমাদের কোড বেস আপডেট না করা পর্যন্ত আমরা সুইফ্ট 3 পর্যন্ত অপেক্ষা করব।
ড্যানিয়েল রায়ান

0

বা এর সাথে সামান্য ফাংশন সংশোধন:

func logFunctionName(file:String = __FILE__, fnc:String = __FUNCTION__, line:(Int)=__LINE__) {
    var className = file.lastPathComponent.componentsSeparatedByString(".")
    println("\(className[0]):\(fnc):\(line)")

}

/ * এর ফলে একটি এক্সিকিউশন ট্রেস তৈরি করবে: অ্যাপডেলিগেট: অ্যাপ্লিকেশন (_: didFinishLaunchingWithOptions :): 18 প্রোডাক্ট: আরআইআই (টাইপ: নাম: বছর: দাম :): 34 ফার্স্টভিউ কনট্রোলার: ভিউডিডলড (): 15 অ্যাপডিজিট: অ্যাপ্লিকেশনডিডকোম্যাক্টিভ: 62 * /


0

আমি ব্যবহার করি, এটি একটি সুইফ্ট ফাইলে যা প্রয়োজন তা সমস্ত, অন্যান্য সমস্ত ফাইল এটি বাছাই করবে (বৈশ্বিক ফাংশন হিসাবে)। আপনি যখন অ্যাপ্লিকেশনটি প্রকাশ করতে চান কেবল লাইনের বাইরে মন্তব্য করুন।

import UIKit

func logFunctionName(file:NSString = __FILE__, fnc:String = __FUNCTION__){  
    println("\(file.lastPathComponent):\(fnc)")
}

0

সুইফট 3.0

public func LogFunction<T>(object: T, filename: String = #file, line: Int = #line, funcname: String = #function) {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MM/dd/yyyy HH:mm:ss:SSS"
    let process = ProcessInfo.processInfo()
    let threadId = "?"
    print("\(dateFormatter.string(from:Date())) \(process.processName) [\(process.processIdentifier):\(threadId)] \(filename)(\(line)) \(funcname)::: \(object)")
}

0

সুইফট 3.x +

আপনি যদি পুরো ফাইলের নামটি না চান তবে তার জন্য এখানে একটি দ্রুত ফিক্স।

func trace(fileName:String = #file, lineNumber:Int = #line, functionName:String = #function) -> Void {
    print("filename: \(fileName.components(separatedBy: "/").last!) function: \(functionName) line: #\(lineNumber)")
}

filename: ViewController.swift function: viewDidLoad() line: #42

0

ফাংশন কল লগ করার অন্য উপায়:

NSLog("\(type(of:self)): %@", #function)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.